首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BigFloat有时会从除法返回NaN

BigFloat有时会从除法返回NaN
EN

Stack Overflow用户
提问于 2017-04-09 20:06:10
回答 1查看 221关注 0票数 2

我不明白为什么除法的结果是NaN,而以前,结果是预期的,而看起来是执行相同的除法。

移除Math::BigFloat时,不返回Nan。但是为什么会发生这种情况呢?

对应的代码(Perl):

代码语言:javascript
复制
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";

结果:

代码语言:javascript
复制
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输出:

代码语言:javascript
复制
$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
EN

回答 1

Stack Overflow用户

发布于 2017-04-10 21:34:18

很抱歉,我花了这么长时间来看这个。

问题是,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_num是一个Math::BigInt对象,这很好。但是$sum_drmsd需要被初始化为Math::BigFloat->bzero,而不仅仅是0,否则您只是在累加普通数字

这段代码演示了这个问题

代码语言:javascript
复制
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";

输出

代码语言:javascript
复制
sum = 10.9829799095931 / 10 = NaN

但如果我只改了这行

代码语言:javascript
复制
my $sum_drmsd = 0

代码语言:javascript
复制
my $sum_drmsd = Math::BigFloat->bzero

然后我就会得到正确的输出

输出

代码语言:javascript
复制
sum = 10.9829799095931 / 10 = 1.09829799095931

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43306483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档