Math :: BigFloat有时会从分区返回NaN

时间:2017-04-09 12:06:10

标签: perl nan division

我无法弄清楚为什么分裂的结果是NaN,之前的结果是预期的,而看似执行相同的分裂。

删除Math :: BigFloat时,不会返回Nan。但为什么会这样呢?

相应的代码(Perl):

use Math::BigFloat ':constant';

...

my $num1 = $sum_drmsd / $k_dists_num;
print "\nsum = $sum_drmsd DIV BY $k_dists_num = $num1\n";

if(looks_like_number($sum_drmsd)){

    print "numerator check ->> yes, is num.";
}

if (looks_like_number($k_dists_num)){
    print "\ndenominator check ->> yes, is num.";
}
print "\n";

结果:

sum = 11.2691792732961 DIV BY 10 = 1.12691792732961
numerator check ->> yes, is num.
denominator check ->> yes, is num.

sum = 13.4679575690216 DIV BY 10 = 1.34679575690216
numerator check ->> yes, is num.
denominator check ->> yes, is num.

sum = 10.9829799095931 DIV BY 10 = 1.09829799095931
numerator check ->> yes, is num.
denominator check ->> yes, is num.

sum = 11.2691792732961 DIV BY 10 = NaN
numerator check ->> yes, is num.
denominator check ->> yes, is num.

sum = 13.4679575690216 DIV BY 10 = NaN
numerator check ->> yes, is num.
denominator check ->> yes, is num.

sum = 10.9829799095931 DIV BY 10 = NaN
numerator check ->> yes, is num.
denominator check ->> yes, is num.

编辑:

每种情况下

Data :: Dumper输出:

$sum_drmsd = '10.9829799095931';
$k_dists_num = '10';
1.9997

$sum_drmsd = '10.9829799095931';
$k_dists_num = bless( {
                        'sign' => '+',
                        'value' => [
                                     10
                                   ]
                      }, 'Math::BigInt' );
1.9997

1 个答案:

答案 0 :(得分:2)

对不起,我花了很长时间才到处看这个。

问题是use Math::BigFloat没有自动使所有浮点运算使用该模块;它只是提供了创建Math::BigFloat对象的代码,如果你以这种方式编写程序,就像任何其他面向对象的模块一样

模块重载算术运算符,以便将$x / $y除以$x->bdiv($y)调用执行。因此,$x必须是一个对象(因为简单数字不具有bdiv方法)更清楚,但事实上$y可能是一个对象,数字或数字字符串。如果传递一个简单的数字,模块会将第二个参数转换为对象

在您的代码中$sum_drmsd不是Math::BigFloat对象,它只是一个浮点值。这就是为什么我问你价值观来自哪里,但你的回答并没有多大帮助,因为我需要了解他们的起源

  

$k_dists_num是函数作为参数立即接收的值,$sum_drmsd初始化为0,然后在循环中用于添加从矩阵接收的值

从您显示的转储中,$k_dists_numMath::BigInt对象,这很好。但$sum_drmsd需要初始化为Math::BigFloat->bzero,而不仅仅是0,否则您只会累积普通数字

此代码演示了问题

use strict;
use warnings 'all';

use Math::BigFloat;

my $k_dists_num = Math::BigInt->new('10');
my $sum_drmsd   = 0;

$sum_drmsd += 10.9829799095931;

my $quot = $sum_drmsd / $k_dists_num;

print "sum = $sum_drmsd / $k_dists_num = $quot\n";

输出

sum = 10.9829799095931 / 10 = NaN

但是,如果我只更改行

my $sum_drmsd = 0

my $sum_drmsd = Math::BigFloat->bzero

然后我得到了正确的输出

输出

sum = 10.9829799095931 / 10 = 1.09829799095931

请注意,我还建议删除:constant选项,否则很容易混淆哪些变量是Math::BigFloat个对象,哪些是简单数字(就像你做的那样!)