计算base-10 log特性时的PERL精度错误

时间:2016-10-31 04:40:20

标签: perl floating-point precision

我意识到非二次幂数字的FP表示总是有错误但是......

% perl -e 'print int(log(1000)/log(10))."\n"'
2
% perl -e 'print (log(1000)/log(10))."\n"'
3
% perl -v

This is perl 5, version 22, subversion 2 (v5.22.2) built for darwin-thread-multi-2level

... oy ...找到基数为10(或任意基数)对数的特征(整数部分)的解决方法是什么?谢谢!

编辑:POSIX :: floor()产生相同的结果。所以问题是,如果我遇到舍入错误,如何计算对数的特征呢?

1 个答案:

答案 0 :(得分:3)

2.999....未舍入为3之前,您需要比默认小数位多很多。

尝试:

$ perl -e 'printf "%.17f\n",log(1000)/log(10)'
2.99999999999999956

int是浮动的底线:

$ perl -e 'print int(2.999)."\n"'
2

处理float的浮动部分和整数部分的标准方法包含在POSIX模块中。

您可以将整数部分和浮动部分与modf

分开
$ perl -MPOSIX -e '($fp, $ip)=modf(3.14); print "$fp $ip\n"'
0.14 3

或者,在您的情况下:

$ perl -MPOSIX -e '($fp, $ip)=modf(log(1000)/log(10)); printf "%.17f %i\n",$fp,$ip '
0.99999999999999956 2

您还可以将ceilfloorfxexpround用于这些功能的标准版本。

如果您关心精确,可能需要轻松部分修复才能使用bignum库:

$ perl -Mbignum -e 'printf "%.30f\n",log(1000)/log(10)'
3.000000000000000000000000000000

或者,作为一个pragma:

$ perl -MPOSIX -e 'use bigint; ($fp, $ip)=modf(log(1000)/log(10)); printf "%.45f %i\n",$fp,$ip'
0.000000000000000000000000000000000000000000000 3

或者,由于logtranscendental function,因此请使用符号数学包。