Using Perl to split a float
Why did I lose precision with split? My goal is to get only the fractional part, all this.
$a = 123456789.123456789;
@b = split(/\./, $a);
$baseDec = "." . $b[1];
The above is $ baseDec ==. 123457
But it gives the correct accuracy: Is it correct? CORRECTION: THIS GIVES THE SAME FIVE ACCURACY! I have not tested the code correctly. Excuse me!
$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 Perl to work with longdouble, I cannot verify the original question. The answer seems to be that I have lost precision because $ a is stored in double (52 bits ~ 15 decimal digits as @Ben pointed out below). print $a
gives 123456789.123457
.
source to share
I'm making a few assumptions based on context, but you lost precision because it 123456789.123456789
is in your program as a numeric literal, which the Perl compiler stores in longdouble $a
. Then, when @b = split(/\./, $a);
executed, it is $a
implicitly forced into the string before it can be split
. By default, the behavior of your longdouble (80 bits of precision ~ 21 decimal digits) doubles (52 bits ~ 15 decimal digits) and your number becomes 123456789.1234567
before it becomes "123456789.1234567"
.
As others have said, you can get around this by using sprintf()
. You don't need Math :: BigFloat unless you are using numbers greater than longdouble
, but you need to exercise caution about when and how your numbers are represented as strings.
* For fun, you can check the size of your datatypes by running perl -V
and find these lines in the section Compiler
:
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
If d_longdbl
none were defined or yours longdblsize
was no more than eight bytes, your numeric literal would be truncated at compile time, but it isn't, so we already know that your Perl installation is capable of
source to share