- 主题:这个结果为什么不对
line="5+50*3/20 + (19*2)/7"
echo "scale=3; $line" | bc -l
# 输出 17.928
# 精确值:17.9285714286
# 不应该是17.929吗?
line="-105+50*3/20 + (19^2)/7"
echo "scale=3; $line" | bc -l
# 输出 -45.929
# 精确值:-45.9285714286
# 这个和期望的一致
--
修改:eskimo1024 FROM 14.112.218.*
FROM 14.112.218.*
不懂 bc 的逻辑,换 awk 解决的
awk "BEGIN {printf \"%.3f\n\", $line}"
bc 的四舍五入逻辑有点怪,奇数不进位,偶数进位。
-l参数默认20位有效数字,也能解决。
printf "%.3f" $(bc -l <<< $line)
【 在 eskimo1024 的大作中提到: 】
: line="5+50*3/20 + (19*2)/7"
: echo "scale=3; $line" | bc -l
: # 输出 17.928
: # 精确值:17.9285714286
: # 不应该是17.929吗?
: line="-105+50*3/20 + (19^2)/7"
: echo "scale=3; $line" | bc -l
: # 输出 -45.929
: # 精确值:-45.9285714286
: # 这个和期望的一致
--
修改:eskimo1024 FROM 14.112.218.*
FROM 14.112.218.*
bc 的 scale 就不会四舍五入,它就是直接按位数去截断结果
至于第二个结果为啥是正确的,你可以计算:
-105 + 7.500 + 51.571
【 在 eskimo1024 的大作中提到: 】
: 不懂 bc 的逻辑,换 awk 解决的
: awk "BEGIN {printf \"%.3f\n\", $line}"
: bc 的四舍五入逻辑有点怪,奇数不进位,偶数进位。
: ...................
--
FROM 117.152.202.*
你这个例子的计算结果是对的
有限小数,结果是精确的,bc 会忽略 scale 变量。
【 在 snoopyzhao 的大作中提到: 】
: 标 题: Re: 这个结果为什么不对
: 发信站: 水木社区 (Sat Jul 9 16:06:09 2022), 站内
:
: bc 的 scale 就不会四舍五入,它就是直接按位数去截断结果
:
: 至于第二个结果为啥是正确的,你可以计算:
:
: -105 + 7.500 + 51.571
:
: 【 在 eskimo1024 的大作中提到: 】
: : 不懂 bc 的逻辑,换 awk 解决的
: : awk "BEGIN {printf \"%.3f\n\", $line}"
: : bc 的四舍五入逻辑有点怪,奇数不进位,偶数进位。
: : ...................
:
: --
:
: ※ 来源:·水木社区 mysmth.net·[FROM: 117.152.202.*]
--
修改:eskimo1024 FROM 14.112.218.*
FROM 14.112.218.*
bc 计算结果没什么道理。我再给一组数据:
bc.txt:
scale=3; -1/17
scale=20; -1/17
/*
-.058
-.05882352941176470588
*/
scale=3; 1 - 1/17
scale=20; 1 - 1/17
/*
.942
.94117647058823529412
*/
scale=3; 1/3 - 1/17
scale=20; 1/3 - 1/17
/*
.275
.27450980392156862745
*/
scale=3; -1/3 - 1/17
scale=20; -1/3 - 1/17
/*
-.391
-.39215686274509803921
*/
scale=3; -1/3 + 1/17
scale=20; -1/3 + 1/17
/*
-.275
-.27450980392156862745
*/
--
修改:eskimo1024 FROM 14.112.218.*
FROM 14.112.218.*
【 在 eskimo1024 的大作中提到: 】
: 你这个例子的计算结果是对的
: 有限小数,结果是精确的,bc 会忽略 scale 变量。
你没有明白我的意思
bc 根本不四舍五入,在你前面给的例子中,它的做法是对每一部分进行 scale,然后再加和……我给的那三项,就是你的那个式子中的三项的 scale 后的结果
--
FROM 117.152.202.*
【 在 eskimo1024 的大作中提到: 】
: 标 题: Re: 这个结果为什么不对
: 发信站: 水木社区 (Sat Jul 9 21:42:28 2022), 站内
:
: bc 计算结果没什么道理。我再给一组数据:
: bc.txt:
:
: scale=3; -1/17
: scale=20; -1/17
: /*
: -.058
scale 根本就不四舍五入,它就是直接截断
: -.05882352941176470588
: */
:
: scale=3; 1 - 1/17
这个的计算过程是 1 - 0.058 = 0.942,而不是先算出来 0.94117 再四舍五入得 0.941
: scale=20; 1 - 1/17
: /*
: .942
: .94117647058823529412
: */
:
: scale=3; 1/3 - 1/17
: scale=20; 1/3 - 1/17
: /*
: .275
: .27450980392156862745
: */
:
: scale=3; -1/3 - 1/17
: scale=20; -1/3 - 1/17
: /*
: -.391
: -.39215686274509803921
: */
:
: scale=3; -1/3 + 1/17
: scale=20; -1/3 + 1/17
: /*
: -.275
: -.27450980392156862745
: */
:
: --
:
: ※ 修改:·eskimo1024 于 Jul 9 21:43:29 2022 修改本文·[FROM: 14.112.218.*]
: ※ 来源:·水木社区 mysmth.net·[FROM: 14.112.218.*]
--
修改:eskimo1024 FROM 14.112.218.*
FROM 117.152.202.*
你说的很有道理,
摘抄 man bc 的部分内容,
除法和取余,作了较详细的说明,但加和乘,都没说明 scale,估计假定用户知道吧。
Every expression has a scale.
This is derived from the scale of original numbers, the operation performed and in many cases, the value of the variable scale.
Legal values of the variable scale are 0 to the maximum number representable by a C integer.
expr + expr
The result of the expression is the sum of the two expressions.
expr * expr
The result of the expression is the product of the two expressions.
expr / expr
The result of the expression is the quotient of the two expressions.
The scale of the result is the value of the variable scale.
expr % expr
The result of the expression is the "remainder" and it is computed in the following way. To compute a%b, first a/b is computed to scale digits. That result is used to compute a-(a/b)*b to the scale of the maximum of scale+scale(b) and scale(a). If scale is set to zero and both expressions are integers this expression is the integer remainder function.
【 在 snoopyzhao 的大作中提到: 】
: scale 根本就不四舍五入,它就是直接截断
: 这个的计算过程是 1 - 0.058 = 0.942,而不是先算出来 0.94117 再四舍五入得 0.941
--
修改:eskimo1024 FROM 113.81.170.*
FROM 113.81.170.*
学习了,那在需要四舍五入的场合,不用bc该用啥?
【 在 snoopyzhao 的大作中提到: 】
: 你没有明白我的意思
: bc 根本不四舍五入,在你前面给的例子中,它的做法是对每一部分进行 scale,然后再加和……我给的那三项,就是你的那个式子中的三项的 scale 后的结果
--
FROM 216.240.30.*
我回帖给了解决办法啊~
bc -l
20位有效数字,再用 printf 做四舍五入
当然,bc可以是任意精度,指定 scale=100 都不会有问题。
awk 也可以,但我不知道背后的原理。
【 在 cjohny 的大作中提到: 】
: 学习了,那在需要四舍五入的场合,不用bc该用啥?
--
修改:eskimo1024 FROM 113.81.170.*
FROM 113.81.170.*