Skip Menu |

This queue is for tickets about the Math-Currency CPAN distribution.

Report information
The Basics
Id: 27691
Status: rejected
Priority: 0/
Queue: Math-Currency

People
Owner: Nobody in particular
Requestors: lloy0076 [...] adam.com.au
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.44
Fixed in: (no value)



Math::Currency uses the following formula to calculate "as_int()": sub as_int { my $self = shift; return Math::BigInt->new( $self->as_float * 10**$self->format()->{FRAC_DIGITS} )->bstr; } This introduces errors if the number of digits is not the expected "2 digits" and the currency cannot be changed to lowest denominator with a simple exponential function. For example, this would fail if: * You made a locale where FRAC_DIGITS were 3 * You made a locale where 1 pound is 12 shillings Note: this problem isn't solved by declaring the default currency to be US as one could, conceivably want to store more than 2 FRAC_DIGITS. This program demonstrates the problem: --- #!/usr/bin/perl use Math::Currency; Math::Currency->format("INT_FRAC_DIGITS", 3); Math::Currency->format("FRAC_DIGITS", 3); my $m = Math::Currency->new("1.003"); print $m->as_int(); =pod =head1 SYNOPSIS "as_int()" reports incorrect value when *FRAC_DIGITS is not 2. =head1 HOW TO REPEAT =over =item * Run this code and the value returned will be "1003"! =back =cut
Subject: Lack of Subject (My Fault)
From: lloy0076 [...] adam.com.au
Sorry but the lack of a subject was my fault - I honestly forgot to put it in and RT didn't throw an error at me! *aaargh*
Subject: Re: [rt.cpan.org #27691]
Date: Fri, 22 Jun 2007 10:25:11 -0400
To: bug-Math-Currency [...] rt.cpan.org
From: John Peacock <jpeacock [...] rowman.com>
lloy0076@adam.com.au via RT wrote: Show quoted text
> Math::Currency uses the following formula to calculate "as_int()": > > sub as_int { > my $self = shift; > return Math::BigInt->new( > $self->as_float * 10**$self->format()->{FRAC_DIGITS} )->bstr; > } > > This introduces errors if the number of digits is not the expected "2 > digits" and the currency cannot be changed to lowest denominator with a > simple exponential function.
I'll excerpt the POD for as_int(): Show quoted text
>$m->as_int - bare integer number of "minimum value" > Some US credit card gateways require all transactions to be > expressed in pennies (because their software isn't running > Math::Currency!). This object method returns an integer value that > corresponds to the currency value multiplied by 10 to the power of > the number of decimal places of precision. Essentially, this > expresses the currency amount in the smallest discrete value > allowed with that currency, so for currency expressed in dollars, > this method returns the same value in pennies.
The code above does exactly what I intended, which is to return the currency value in terms of the "minimal currency unit" for that currency. In the case of dollars, the minimal currency unit is the penny, which are 100 to the dollar. In the case of some currency with 3 decimal place accuracy, say BUCKS, the minimal unit would be 1000 to the "BUCK". Show quoted text
> * You made a locale where 1 pound is 12 shillings
It is true that this module won't work with non-decimal currencies; are there still any left in the world? It would be possible to support pre-decimalized British currency as a completely independent class with different syntax (how would you notate "2 pounds 6 pence"?). But that lies outside of my scope... John -- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4501 Forbes Boulevard Suite H Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5748
Subject: as_int() won't work with non-decimal currency
Although I think as_int() works the way it was designed (i.e. it won't handle non-decimal currency), but someone just reported a different problem with it in: http://rt.cpan.org/Ticket/Display.html?id=29210 so I'll make a release as soon as I confirm that I've fixed that bug. Thanks John