Rob Coops wrote:
>
> Thank you all that replied, in the end I copied the rules I learned in
> elementary school about how to round a number to two decimals. I'm sure it
> is a horrible hack and can be done a lot faster, but with a country not
> being able to process their invoices into the accounting system this was the
> best way I could come up with that didn't in some cases result in a error.
> I am not using any of the suggested modules because the production system is
> outside of my control and getting a module installed can take days if not
> longer due to processes procedures forms and so on. The country has only a
> few days left till the end of the month by which time this should absolutely
> be working.
>
> This is the routine as it looks now (I would be happy to hear about errors
> or improvements that you might see)
> sub round {
> my $number = shift;
> if ( $number == 0 ) { return 0.00; }
> if ( length( $number ) <= 4 ) { return $number; }
> my $int = int( $number ); # Get the whole number
> my $dec = $number - $int; # Get the decimals only
>
> $dec = sprintf( "%.15f", $dec ) * 1000000000000000;
>
> my @digits = split( //, $dec );
> my @reverse_digits = reverse( @digits );
> my $number_of_digits = $#reverse_digits - 1;
>
> my $remember = 0;
> my $tracker = 0;
> for( my $x = 0; $x <= $number_of_digits; $x++ ) {
> $reverse_digits[$x] = $reverse_digits[$x] + $remember;
> my $result = $reverse_digits[$x] + 5;
> if ( $result >= 10 ) {
> $remember = 1;
> } else {
> $remember = 0;
> }
> $tracker = $x;
> }
>
> if ( $reverse_digits[$tracker] >= 10 ) {
> $reverse_digits[$tracker] = $reverse_digits[$tracker] - 10;
> $reverse_digits[$tracker + 1]++;
> if ( $reverse_digits[$tracker + 1] == 10 ) {
> $reverse_digits[$tracker + 1] = 0;
> $int++;
> }
> }
> my @reordered_digits = reverse(@reverse_digits);
> splice( @reordered_digits, 2 );
> my $decimal_amount = join( '', @reordered_digits );
> return "$int.$decimal_amount";
> }
I tried it out. Is this supposed to be correct?
$ perl Perl_rounding_errors.pl
0.524 --> 0.52
0.5241 --> 0.52
0.5242 --> 0.52
0.5243 --> 0.52
0.5244 --> 0.52
0.5245 --> 0.53
0.5246 --> 0.53
0.5247 --> 0.53
0.5248 --> 0.53
0.5249 --> 0.53
John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway
Thread Previous
|
Thread Next