Perl 转换为 int 错误但仅限于特定数字
下面的 Perl 代码将浮点数转换为错误的整数
use strict;
my $zahl =297607.22000;
$zahl=$zahl * 100;
print "$zahl\n";
my $text=sprintf ("%017d",$zahl);
print $text;
其输出是:
29760722
00000000029760721
事实是,您可以将给定的数字更改为其他数字,并且它可以工作。
知道这里出了什么问题吗?还是 Perl 只是做错了?
感谢您的帮助!
the following perl code converts a float number to the wrong integer number
use strict;
my $zahl =297607.22000;
$zahl=$zahl * 100;
print "$zahl\n";
my $text=sprintf ("%017d",$zahl);
print $text;
The output of this is :
29760722
00000000029760721
The thing is, you can change the given number to other numbers and it works.
Any idea what is wrong here or does Perl simply do it wrong?
Thanks for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这与常见问题解答相关(为什么我得到了很长的小数)。
$zahl
未正确舍入,它向下舍入到下一个较小的整数。This is related to a FAQ (Why am I getting long decimals).
$zahl
is not rounded properly, it is rounded down to the next lower integer.22/100
是二进制周期数,就像 1/3 是十进制周期数一样。将其精确地存储在浮点数中需要无限的存储空间。int
和sprintf %d
截断小数,因此最终得到 29760721。print
和sprintf %f
四舍五入,这样你就可以获得想要的结果。22/100
is a periodic number in binary just like 1/3 is a periodic number in decimal. It would take infinite storage to store it exactly in a floating point number.int
andsprintf %d
truncate decimals, so you end up with 29760721.print
andsprintf %f
round, so you can get the desired result.当您进行浮点乘以 100 时,结果将类似于
29760721.9999999963
。然后,当您将%d
转换为整数时,该值将被截断为29760721
。尝试
sprintf('%.10f', $zahl)
你应该能够看到这一点。When you are doing your floating point multiplication by 100 the result will be something like
29760721.9999999963
. Then when you do the%d
conversion to an integer this is truncated to29760721
.Try
sprintf('%.10f', $zahl)
and you should be able to see this.您必须非常小心浮点数并将它们视为定点。由于内置函数中可能发生各种转换,有时一个整数转换可能与另一个不完全相同。看来这种情况在
x.22
数字上发生过很多次:在我的系统上打印
。
需要仔细查看 Perl 源代码才能了解确切的转换差异在哪里。
我建议,如果您要使用定点数,请将它们全部转换为整数(使用通用转换函数,最好将源数字视为字符串),然后在
下使用它们使用integer;
pragma 它将禁用浮点数。You have to be really careful with floating point numbers and treating them as fixed point. Due to various conversions that may take place in the builtins, there may be times where one integer conversion is not exactly the same as another. It appears that this happens many times with
x.22
numbers:which prints
on my system.
A careful look at the Perl source would be required to see where the exact conversion difference is.
I would recommend that if you are going to be working with fixed point numbers, to convert them all to integers (using a common conversion function, preferably looking at the source numbers as strings), and then work with them all under the
use integer;
pragma which will disable floating point numbers.