Я теряю точность при выполнении арифметических операций или попытке напечатать (отладить) такие большие числа: 1234567890.123456789
Я думаю, что мои проблемы связаны с $d (результат арифметики) и форматированной печатью $e. Как я могу заставить длинные удвоения? Моя версия Perl (5.8.4 на SUN) говорит, что это возможно. В sprintf есть параметр размера для длинных удвоений (q, L или ll), но я не понял, как его использовать, и не знаю, будет ли он работать с printf.
Редактировать: я добавил BigFloat, который работает! Но я все равно хотел бы форсировать длинные удвоения.
Попробуйте сложить 1234567890 + 0,123456789 и вычесть 1234567890 - 0,123456789.
use Config;
use Math::BigFloat;
$a = 1234567890;
$b = 123456789;
$c = $b/1e9; # 0.123456789
$d = $a + $c; # not enough precision (32-bit or double?)
$e = sprintf("%d.%.9d",$a,$b); # combine as strings
$f = 1234567890.123456789; # for reference (not enough precision)
# Use BigFloat to bypass lack of longdbl
$aBig = Math::BigFloat->new("$a");
$dSum = $aBig->fadd("$c"); # $dSum = $a + $c
$aBig = Math::BigFloat->new("$a"); # <-- Need a new one for every operation?
$dDif = $aBig->fsub(abs("$c")); # $dDif = $a - $c
print "a $a\n"; # 1234567890
print "c $c\n"; # 0.123456789
print "d=a+c $d\n"; # 1234567890.12346 <-- **Problem**
print "dSum=a+c $dSum\n"; # 1234567890.123456789 <-- Solution
print "dDif=a-c $dDif\n"; # 1234567890.876543211 <-- Solution
print "e $e\n"; # 1234567890.123456789
print "f $f\n"; # 1234567890.12346 <-- double, 52-bit, not longdbl?
printf ("printf e 20.9f %20.9f\n",$e); # 1234567890.123456717 <-- **Problem**
printf ("printf dSum 20.9f %20.9f\n",$dSum); # 1234567890.123456717 <-- **Problem**
printf ("printf dSum 20s %20s\n",$dSum); # 1234567890.123456789
printf ("printf dDif 20.9f %20.9f\n",$dDif); # 1234567890.876543283 <-- **Problem**
printf ("printf dDif 20s %20s\n",$dDif); # 1234567890.876543211
print "uselongdouble $Config{uselongdouble}\n"; # empty. No long doubles by default
print "d_longdbl $Config{d_longdbl}\n"; # "define". Supports long doubles
print "size double longdbl $Config{doublesize} $Config{longdblsize}\n"; # Ans 8 16
Я также использовал этот код, чтобы попытаться понять типы, но это не очень помогло. Кто-нибудь использовал его для объяснения подобных проблем?
use Devel::Peek 'Dump';
Dump ($dSum); # Wow, it's complicated
Dump ($f);
$Config{uselongdouble}
, для которого требуетсяuse Config
- person Borodin   schedule 14.01.2015