【问题标题】:How do you downgrade a bigrat?你如何降级一个大老鼠?
【发布时间】:2017-05-26 23:31:13
【问题描述】:
perl -Mbigrat -E'for (1..100) { $i += 1/3; say int($i), "\t", sprintf "%.55f", $i }'

垃圾邮件很多警告:

Argument "100/3" isn't numeric in addition (+) at …/site_perl/5.24.1/Math/BigRat.pm line 1939.

在不使用-Mbigrat 的情况下再次运行以查看 sprintf 所需的效果。

如何将Math::BigRat 实例$i 降级为普通的NV 可享受到sprintf

版本:

  • bigrat0.47
  • Math::BigRat0.2612

【问题讨论】:

  • FWIW bigrat @ 0.39 和 Math::BigRat 在 0.2608 没有这个警告。将 bigrat 升级到 0.47,这会带来 Math-BigInt-1.999811,确实有一个警告,但它是 Use of uninitialized value in string eq at .../5.22.2/Math/BigFloat.pm line 3626.Manually更新 Math::BigRat 给我你的警告。
  • 您报告过这个问题了吗?

标签: perl bignum


【解决方案1】:

我希望Math::BigRat 提供一种获取纯数字的方法,它确实做到了:

  • as_int 表示整数
  • as_float 用于花车

出于调试目的,我插入了 $_ 的打印。

$i->as_int()int($i) 的作用相同:

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", sprintf "%.55f", $i->as_int() }'
...
99      33      33.0000000000000000000000000000000000000000000000000000000
100     33      33.0000000000000000000000000000000000000000000000000000000

$i->as_float() 乍一看似乎按预期工作,但我不明白输出。所有小数位均为零,并且每隔一行 $i 等于 $_

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", sprintf "%.55f", $i->as_float() }'
...
90      30      30.0000000000000000000000000000000000000000000000000000000
91      30      91.0000000000000000000000000000000000000000000000000000000
92      30      92.0000000000000000000000000000000000000000000000000000000
93      31      31.0000000000000000000000000000000000000000000000000000000
94      31      94.0000000000000000000000000000000000000000000000000000000
95      31      95.0000000000000000000000000000000000000000000000000000000
96      32      32.0000000000000000000000000000000000000000000000000000000
97      32      97.0000000000000000000000000000000000000000000000000000000
98      32      98.0000000000000000000000000000000000000000000000000000000
99      33      33.0000000000000000000000000000000000000000000000000000000
100     33      100.0000000000000000000000000000000000000000000000000000000

这是带有 Math::BigRat 0.2614 的 Perl 5.30.0。

因此警告已修复,但此解决方案似乎有问题。

更新:在没有sprintf的cmets中要求:

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", $i->as_float() }'
...
90      30      30
91      30      91
92      30      92
93      31      31
94      31      94
95      31      95
96      32      32
97      32      97
98      32      98
99      33      33
100     33      100

【讨论】:

  • 如果省略 sprintf 并直接打印 as_float 会怎样?看起来你得到的是简化形式的分数的分子,而不是正确的数值。
【解决方案2】:

没有那么严肃的答案:

use bigrat;
use feature 'say';
for (1..100) {
    $i += 1/3;
    no bigrat;
    say int($i),"\t",sprintf "%.55f", eval "$i"
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-31
    • 2022-06-16
    • 2022-06-15
    • 2023-02-02
    • 1970-01-01
    • 2016-05-20
    • 2017-09-21
    • 1970-01-01
    相关资源
    最近更新 更多