Why did I lose precision using split? My goal is to get just the fractional part, all of it.
$a = 123456789.123456789;
@b = split(/\./, $a);
$baseDec = "." . $b[1];
Above gives $baseDec == .123457
But this gives the correct precision: Is it the right way to do it? CORRECTION: THIS GIVES THIS SAME BAD PRECISION! I did not properly test the code. Sorry!
$a = 123456789.123456789;
@b = split(/\./, $a);
$baseInt = $b[0];
$baseDec = $a - $baseInt;
Should I be using Math::BigFloat?
Edit: $a should be a string $a = "123456789.123456789";
and then the original code works. Until I figure out how to get my Perl to work with longdouble, I can't test the original question. The answer seems to be that I lost precision because $a is being stored in a double (52 bits ~ 15 decimal digits, as @Ben stated below). print $a
gives 123456789.123457
.
You can use int
:
$a = 123456789.123456789;
$baseDec = $a - int($a);
You lost precision because 123456789.123456789
is a numeric literal which, by default, the Perl compiler stores in a double
(52 bits, ~15 decimal digits) $a
. Next, when @b = split(/\./, $a);
runs, $a
is implicitly coerced into a string before it can be split
.
If your Perl were compiled to use longdouble
s (See: perl -V:uselongdouble
and perl -V:doublesize
), the numeric literal would have been represented with 80 bits (~21 decimal digits) and string coercion.
IF you're going to treat it as a string, do so all the way through. You wouldn't assign a string without quoting, right?
my $a = "123456789.123456789";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With