Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^4: number comparison with a twist

by anotherguest (Novice)
on Mar 05, 2020 at 13:39 UTC ( [id://11113850]=note: print w/replies, xml ) Need Help??


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

No, truncation is correct in this case. It's not that the API returns exact binary float representations, it returns prices but somehow decided to use strings as a transport and return fractional cent digits which have been all zero for now but will throw an error in my script because they CANNOT match what's in my database because this in turn stores the prizes as integer cents.

So the context in this specific case calls for truncating as the rounding error seen in my original post was introduced by storing the string representation into a binary float.
I need to use the exact value as returned by the API, not rounded, if the API is off by one cent, it is considered an error.

Replies are listed 'Best First'.
Re^5: number comparison with a twist
by pryrt (Abbot) on Mar 05, 2020 at 15:09 UTC
    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
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11113850]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-04-24 13:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found