Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^5: number comparison with a twist

by pryrt (Prior)
on Mar 05, 2020 at 15:09 UTC ( #11113855=note: print w/replies, xml ) Need Help??


in reply to Re^4: number comparison with a twist
in thread number comparison with a twist

No, truncation is correct in this case. ... as the rounding error seen in my original post was introduced by storing the string representation into a binary float

Whatever works for you.

I am just saying that not all price strings translate into a double that is bigger than the string value, and you will want to make sure that your application doesn't have any situations like the following, for the string "1.13", which has a binary representation slightly less than 1.13 for both double precision and single precision:

C:\usr\local\share\PassThru\perl>perl -le "print int(100*'1.13')" 112 C:\usr\local\share\PassThru\perl>perl -MPOSIX=round -le "print round(1 +00*'1.13')" 113

If your application doesn't have that problem, then great.

However, I still don't see why my suggestion won't work for you. It would be nice for you to show me one example of a price-string to put in $from_api that will not become the right integer number of cents when run through my second section of code:

#### redo, with proper rounding $from_api = get_from_api(); print "string from_api = '$from_api' straight from api\n"; $from_api .= '.' unless $from_api =~ /\./; $from_api .= '00'; $from_api =~ s,^(\d+)\.(\d{2})(\d*).*$,${1}${2}.${3},; print "string from_api = '$from_api' after text manipulation\n"; $from_api = round($from_api); print "good rounding = ", $from_api, "cents\n";

Here's a testbed, showing that for reasonable strings, our two match. It also shows a couple strange variants, where there's at least one place where your truncation and my rounding come up with different results.

use warnings; use strict; use POSIX qw/round/; use Test::More; for my $correct_integer_cents ( 0 .. 200 ) { # first, let's create a testbench using the integer number of cent +s as the basis my $price_string = "00" . $correct_integer_cents; $price_string =~ s/(\d{2})$/.$1/; my $price_float = $correct_integer_cents / 100; my $test_name = sprintf "cents=%s str='%s' float='%.15f'", $correc +t_integer_cents, $price_string, $price_float; # Now let's compare how your converter and my converter deal with +these is anotherguest($price_string), $correct_integer_cents, "anothergu +est | $test_name"; is pryrt($price_string), $correct_integer_cents, "pryrt + | $test_name"; } # so both are identical for those 201 tests. # however, what about weird situations for my $price_string ( '1.13', '1.130000000', 1.13 , sprintf('%.18f', +1.13) ) { is anotherguest($price_string), 113, "anotherguest | str='$price_s +tring'"; is pryrt($price_string), 113, "pryrt | str='$price_s +tring'"; } done_testing;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11113855]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2020-05-30 14:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If programming languages were movie genres, Perl would be:















    Results (172 votes). Check out past polls.

    Notices?