我需要读取数据库中的一些数字,并使用Perl将它们写入文本文件。
在数字表中,数据格式定义为numeric (25,5)
(它读取25位数,包括5位小数)。
我使用sprintf "%.5f", $myvalue
格式化我的文件中的数字以强制5位小数,我只是注意到对于大数值,超过17位的数字会有精度损失:
db = 123.12345
file = 123.12345 (OK)
db = 12345678901234891.12345
file = 12345678901234892.00000 (seems to be rounded to upper integer)
db = 12345678901234567890.12345
file = 12345678901234567000.00000 (truncation ?)
Perl对固定十进制数的最高精度是什么?
我一般都知道浮点运算的概念和局限,但我不是Perl和尚,我不知道Perl的内部因此我不知道它是否正常(或者它是否相关)根本不是浮点数)。我不确定它是Perl的内部限制,还是与sprintf
处理相关的问题。
是否有解决方法或专用模块可以帮助解决该问题?
一些值得注意的要点:
答案 0 :(得分:2)
再一次,我在问SO之后就找到了解决方案。我在这里提出我的解决方案,以帮助未来的访客:
替换
$myout = sprintf "%.5f", $myvalue;
通过
use Math::BigFloat;
$myout = Math::BigFloat->new($myvalue)->ffround( -5 )->bstr;
答案 1 :(得分:2)
没有像Math :: BigFloat这样的模块,16位以上的数字都是纯粹的魔法......例如。
perl -e 'printf "*10^%02d: %-.50g\n", $_, log(42)*(10**$_) for (0..20)'
产生
*10^00: 3.7376696182833684112267746968427672982215881347656
*10^01: 37.376696182833683224089327268302440643310546875
*10^02: 373.76696182833683224089327268302440643310546875
*10^03: 3737.6696182833684360957704484462738037109375
*10^04: 37376.6961828336861799471080303192138671875
*10^05: 373766.96182833681814372539520263671875
*10^06: 3737669.6182833681814372539520263671875
*10^07: 37376696.18283368647098541259765625
*10^08: 373766961.82833683490753173828125
*10^09: 3737669618.283368587493896484375
*10^10: 37376696182.83368682861328125
*10^11: 373766961828.33685302734375
*10^12: 3737669618283.36865234375
*10^13: 37376696182833.6875
*10^14: 373766961828336.8125
*10^15: 3737669618283368.5
*10^16: 37376696182833688
*10^17: 373766961828336832
*10^18: 3737669618283368448
*10^19: 37376696182833684480
*10^20: 373766961828336828416
答案 2 :(得分:1)
Perl对固定十进制数的最高精度是什么?
Perl没有定点十进制数。实际上,很少有语言能做到。您可以使用Math::FixedPoint之类的模块,但
答案 3 :(得分:1)
Perl在内部将您的值存储为浮点数。 1 精度取决于您的Perl版本的编译方式,但它可能是64位的两倍。
C:\>perl -MConfig -E "say $Config::Config{doublesize}"
8
64位双精度浮点数 2 具有53位有效数字(a.k.a。分数或尾数),它给出了大约16个精度的十进制字符。您的数据库定义为存储25个字符的精度。如果您将数据视为字符串,那么您会没事的,但如果将其视为数字,则会失去精确度。
Perl的bignum
编译指示为任意大数提供透明支持。它可以大大减慢速度,从而将其使用限制在尽可能小的范围内。如果您只想要大浮点数(不使其他数字类型为“大”),请改用Math::BigFloat
。
<子>
1.在内部,perl使用一种称为SV的数据类型,它可以同时保存浮点数,整数和/或字符串。
2.假设IEEE 754格式。
子>
答案 4 :(得分:0)
或者,如果您只是将值从数据库传输到文本文件而不是作为数字操作它们,那么让DB将它们格式化为字符串。然后阅读并将它们打印成字符串(也许使用&#34; printf&#39;%s&#39;&#34;)。例如:
select Big_fixed_point_col(format '-Z(24)9.9(5)')(CHAR(32))