perl - Why does Math::BigInt has wrong output?
问题描述
I need to get the nearest number $new
to $orig
divisible by $divisor
. The $new
should be greater than $orig
. So I have come with the following formula (hopefully, there is no error in it):
$new = $orig + ($divisor - $orig % $divisor)
Now, the $orig
number is an integer and has up to 30 digits. I want to implement this into a Perl function using Math::BigInt
, but the output is quite wrong.
use Math::BigInt;
Math::BigInt->accuracy(60);
Math::BigInt->precision(60);
my $orig = Math::BigInt->new('5967920747812842369477355441'); # A
my $divisor = Math::BigInt->new('719'); # B
my $modulo = $orig->bmod($divisor); # A % B = M
my $diff = $divisor->bsub($modulo); # B - M = D
my $new = $orig->badd($diff); # A + D = N
my $test = $new->bdiv($divisor); # N / B = 0
print("orig : $orig\n"); # 10; should be: 5967920747812842369477355441
print("modulo : $modulo\n"); # 10; should be: 648
print("diff : $diff\n"); # 71; should be: 71
print("new : $new\n"); # 10; should be: 5967920747812842369477355512
print("test : $test\n"); # 10; should be: 0
解决方案
https://metacpan.org/pod/Math::BigInt#Arithmetic-methods:“这些方法修改调用对象并返回它。” 换句话说,bmod
,bsub
, 和, , , 和,,,和,不badd
一样%=
-=
+=
%
-
+
因此,在您调用其中一种算术方法的任何地方,您都应该先复制,这样您当前调用该方法的对象就不会改变:
use Math::BigInt;
Math::BigInt->accuracy(60);
Math::BigInt->precision(60);
my $orig = Math::BigInt->new('5967920747812842369477355441'); # A
my $divisor = Math::BigInt->new('719'); # B
my $modulo = $orig->copy->bmod($divisor); # A % B = M
my $diff = $divisor->copy->bsub($modulo); # B - M = D
my $new = $orig->copy->badd($diff); # A + D = N
my $test = $new->copy->bmod($divisor); # N % B = 0
print("orig : $orig\n"); # 10; should be: 5967920747812842369477355441
print("modulo : $modulo\n"); # 10; should be: 648
print("diff : $diff\n"); # 71; should be: 71
print("new : $new\n"); # 10; should be: 5967920747812842369477355512
print("test : $test\n"); # 10; should be: 0
(还将您的测试更改为模数,而不是除法。)
推荐阅读
- javascript - 如何在 React 中停止呈现动态搜索结果?
- c++ - 为什么我在初始化 Wintab 扩展后没有收到 WT_PACKETEXT 窗口消息?
- google-cloud-stackdriver - 如何获取跟踪的调用次数
- javascript - 入口点构建时出现 MiniCssExtractPlugin 错误
- node.js - Promise不是函数吗?
- reactjs - 使用钩子将类组件(导航栏)转换为函数式
- ubuntu - 为什么我的 .NET Core 服务器应用程序在 Ubuntu 中不接受连接,但在 Windows 中可以正常工作?
- python - 2个数据帧之间的一对一列值比较 - 熊猫
- python - PIL 图像从 I 模式转换为 P 模式
- sql - 有没有办法收集在不同的多个 SQL 选择语句运行期间返回的列数据?