Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you downgrade a bigrat?

Tags:

perl

bignum

perl -Mbigrat -E'for (1..100) { $i += 1/3; say int($i), "\t", sprintf "%.55f", $i }'

spams a lot of warnings:

Argument "100/3" isn't numeric in addition (+) at …/site_perl/5.24.1/Math/BigRat.pm line 1939.

Run again without -Mbigrat to see the desired effect of sprintf.

How do you downgrade the Math::BigRat instance $i into an ordinary NV delectable to sprintf?

Versions:

  • bigrat 0.47
  • Math::BigRat 0.2612
like image 756
daxim Avatar asked May 26 '17 23:05

daxim


1 Answers

I expected Math::BigRat to provide a method for getting a plain number and it does:

  • as_int for integers
  • as_float for floats

I inserted printing of $_ for debugging purposes.

$i->as_int() does the same as int($i):

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", sprintf "%.55f", $i->as_int() }'
...
99      33      33.0000000000000000000000000000000000000000000000000000000
100     33      33.0000000000000000000000000000000000000000000000000000000

$i->as_float() seemed to work as expected on first sight but I don’t understand the output. All decimal places are zero and for every second line $i equals $_:

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", sprintf "%.55f", $i->as_float() }'
...
90      30      30.0000000000000000000000000000000000000000000000000000000
91      30      91.0000000000000000000000000000000000000000000000000000000
92      30      92.0000000000000000000000000000000000000000000000000000000
93      31      31.0000000000000000000000000000000000000000000000000000000
94      31      94.0000000000000000000000000000000000000000000000000000000
95      31      95.0000000000000000000000000000000000000000000000000000000
96      32      32.0000000000000000000000000000000000000000000000000000000
97      32      97.0000000000000000000000000000000000000000000000000000000
98      32      98.0000000000000000000000000000000000000000000000000000000
99      33      33.0000000000000000000000000000000000000000000000000000000
100     33      100.0000000000000000000000000000000000000000000000000000000

This is Perl 5.30.0 with Math::BigRat 0.2614.

So the warnings are fixed but there seems to be something wrong with this solution.

Update: As requested in the comments without sprintf:

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", $i->as_float() }'
...
90      30      30
91      30      91
92      30      92
93      31      31
94      31      94
95      31      95
96      32      32
97      32      97
98      32      98
99      33      33
100     33      100
like image 114
Daniel Böhmer Avatar answered Oct 11 '22 23:10

Daniel Böhmer