- 主题:这个结果为什么不对
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 变量。
【 在 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.*
你说的很有道理,
摘抄 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 -l
20位有效数字,再用 printf 做四舍五入
当然,bc可以是任意精度,指定 scale=100 都不会有问题。
awk 也可以,但我不知道背后的原理。
【 在 cjohny 的大作中提到: 】
: 学习了,那在需要四舍五入的场合,不用bc该用啥?
--
修改:eskimo1024 FROM 113.81.170.*
FROM 113.81.170.*
任意精度,够酷了,直接扔了尾巴图省事吧。
四舍五入又不是啥好东西。
哈哈,我屁股歪了。
【 在 cjohny 的大作中提到: 】
: 哈,bc还不如bash的printf,简直是耻辱。
--
修改:eskimo1024 FROM 113.81.170.*
FROM 113.81.170.*
printf 没有任意精度,取决于 double float 的精度
我在 bc 的 manual 里没找到明确的取舍规则,如果补上就好了。
所以正确的用法是,先用高精度,再按要求截取。
顺便说下,“四舍五入”本来是有争议的,
有人给了“四舍六入五凑偶”,这个在实验数据的处理过程中使用更普遍。
https://baike.baidu.com/item/%E5%9B%9B%E8%88%8D%E5%85%AD%E5%85%A5%E4%BA%94%E6%88%90%E5%8F%8C/9062547
【 在 cjohny 的大作中提到: 】
: 直接扔尾巴肯定不如四舍五入精确吧?
: 对了,刚才突然想起来,如果bc做不到四舍五入,那就有点儿鸡肋了。
: 整个儿的计算由printf完成不香吗?
--
修改:eskimo1024 FROM 113.81.170.*
FROM 113.81.170.*
做化学实验,课本里讲的。
【 在 cjohny 的大作中提到: 】
: 估计兄台是搞高性能计算的,我之前都没听过“四舍六入五成双”的说法,孤陋寡闻了。
: 谢谢您的分享。
--
FROM 113.81.170.*