我花了几个小时搜索如何在 BASH 中对“浮动数字”进行舍入,但找不到任何正确的!解决方案:( 如果我将这些数字放入 Excel,那么我将在四舍五入到小数点后两位后收到正确的结果:
3.314 -> 3.31
3.315 -> 3.32
8.124 -> 8.12
8.125 -> 8.13
如何在BASH中得到准确的结果?我尝试使用printf
andawk
但没有得到相同的结果
prompt> printf '%.*f\n' 2 8.125
8.12
prompt> echo '8.125' | awk '{printf("%.2f\n", $1)}'
8.12
将使用标准或C 函数
8.125
之类的方法将十进制数的文本表示形式转换为内部二进制表示形式,获得一个或二进制浮点数,其表示形式取决于 C 编译器和计算机体系结构。strtod()
strtold()
double
long double
然后该数字将通过命令传递
printf
给printf()
标准函数(或其将结果返回为字符串的变体),该函数会将其转换回文本十进制表示形式并进行舍入。该四舍五入到最接近的四舍五入,一半到偶数(也称为银行家四舍五入)。您在学校学到的方法存在偏差,因为它往往会平均高估(对于正数)。一半为偶数时, 和 均四舍五入为(偶数
8.125
)8.115
,8.12
一位2
向下舍入,一位向上舍入。对于大量数字,将其中一半数字向下舍入,将其中一个向上舍入,就不会引入系统偏差。现在,这只适用于可以用二进制精确表示的数字。
碰巧,8.125 可以用二进制表示。那是 2 3 + 2 -3。8.135 不能。最接近的 IEEE 754 双精度二进制数是 8.1349999999999997868371792719699442386627197265625(转换回十进制时),因此它将转换为 8.13,因为它最接近,而不是偶数 (8.14)。
因此,要做你想做的事(甚至进行适当的银行四舍五入),你需要一些不能以二进制工作但以十进制工作的东西。因此,任何
printf()
在下面使用的东西,包括printf
实用程序awk
'sprintf()
,或者更一般地与处理二进制数的处理器浮点算术功能一起工作,包括numfmt
在内,都是不可能的。您可以使用 example
perl
的Math::BigFloat
模块。默认情况下,它进行银行四舍五入:但你可以切换到与你在学校学到的模式相匹配的
common
模式:如果您的系统使用 GNU coreutils,则numfmt命令应该可用,并允许您在“向上”、“向下”、“从零”(默认)、“向零”或“最近”舍入之间进行选择。
前任。
您可以添加
0.005
该数字(如学校所教授的那样)以进行计算:对我来说
awk
,打印出数字,所以你可以尝试类似的方法:没有 printf,没有 perl,只有文本操作
测试输出
舍入为整数的标准方法是添加 ½ 并截断:
要实现两位小数乘以 100、截断并再次除法:
或者