Handle huge numbers better
A sufficiently big number, i.e. longer than a long long, had interesting effects. Perl would promote it to a float, and format it as -1 in sprintf, which RevBank::Amount didn't handle correctly. In extreme cases the number got rounded to Inf and would no longer round-trip. As a result, numbers returned by RevBank::Amount are now Math::BigInt and Math::BigFloat objects. Those should be transparent to all existing code. It's amazing to see the unit tests pass. I don't think there is any actual use case in RevBank for numbers this large and I don't think anyone will have actually encountered the aforementioned weird effects. Mostly, the input would be parsed with parse_amount which refuses any number greater than 99900 anyway. Only where parse_string was used directly, such large numbers could actually have been used, but in stock RevBank that is only done when reading the accounts file. This change also introduces a new global function parse_any_amount that is like parse_amount but doesn't complain about negative or large numbers, to further improve the adduser plugin (see previous commit) in insane edge cases. It differs from RevBank::Amount->parse_string in that it does support addition and subtraction operators.
This commit is contained in:
parent
f6f5d66bdc
commit
ef0039bc33
5 changed files with 54 additions and 40 deletions
|
@ -40,6 +40,12 @@ cmp_ok(RevBank::Amount->parse_string("4 ")->cents, '==', 400);
|
|||
|
||||
cmp_ok(RevBank::Amount->new_from_float(.425)->cents, '==', 42);
|
||||
|
||||
|
||||
my $big = "9" x 123;
|
||||
cmp_ok(RevBank::Amount->new($big)->cents, 'eq', $big);
|
||||
cmp_ok(RevBank::Amount->parse_string($big)->cents, 'eq', $big . "00");
|
||||
cmp_ok(RevBank::Amount->new_from_float($big)->cents, 'eq', $big . "00");
|
||||
|
||||
# comparisons
|
||||
ok($a);
|
||||
ok(!RevBank::Amount->new(0));
|
||||
|
@ -136,6 +142,8 @@ like(warning { rand $a }, qr/float/);
|
|||
|
||||
# Invalid amounts
|
||||
|
||||
throws_ok(sub { RevBank::Amount->new(1.1) }, qr/Non-integer/);
|
||||
throws_ok(sub { RevBank::Amount->new("+Inf") }, qr/Infinite/);
|
||||
is(RevBank::Amount->parse_string("0.000"), undef);
|
||||
is(RevBank::Amount->parse_string("0.042"), undef);
|
||||
is(RevBank::Amount->parse_string("+0.042"), undef);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue