davecardwell has asked for the wisdom of the Perl Monks concerning the following question:

Fixed! I had thought it might be an internal storage problem as a floating point, but couldn't find anything, but then found a pesky sprintf in a lesser-used module. Thank you to all who helped.

When doing a >= on three variables, ala:

$hash{'v1'} + $hash{'v2'} >= $value

it returns false when it should return true. When I print the variables before the if it may print, for example, 1742 + 0 >= 1742, but return false.

Most of the time the code works as expected, and I cannot find any changes in the methods of retrieval for the values. The hash values are from a database. The code is running in a mod_perl environment.

Any thoughts on what might be causing this?

Replies are listed 'Best First'.
Re: >= returning unexpected result
by tlm (Prior) on Apr 12, 2005 at 10:44 UTC

    Did any of the values involved arise from a floating point computation? print can produce misleading output in such situations. For example:

    $x = 1742-1e-12; $y = 0; $z = 1742; print "$x + $y >= $z is ", ( $x + $y >= $z ? 'true' : 'false', "\n"; __END__ 1742 + 0 >= 1742 is false
    In this case, >= is correct; print is just misleading you. If this diagnosis is correct, the Numbers section of perlfaq4 is worth reading, as is perlnumber. To get trustier ints the general solution is to use sprintf. For example:
    sub round { my $number = shift; my $precision = shift || 0; # optional precision my $template = "%.${precision}f"; return sprintf $template, $number; } $x = round( 1742-1e-12 ); $y = round( 0 ); $z = round( 1742 ); print "$x + $y >= $z is ", ( $x + $y >= $z ? 'true' : 'false', "\n"; __END__ 1742 + 0 >= 1742 is true

    the lowliest monk

Re: >= returning unexpected result
by gjb (Vicar) on Apr 12, 2005 at 10:44 UTC

    Do things go wrong only on equality? If so, it may point to some round off error due to the numeric representation. See e.g. BrowserUk's excellent node on the topic.

    Hope this helps, -gjb-

Re: >= returning unexpected result
by cog (Parson) on Apr 12, 2005 at 09:47 UTC
    Any thoughts on what might be causing this?

    More code, perhaps?

    How are you printing those values? Show us the two/three lines before/after that condition, print statement included.

Re: >= returning unexpected result
by polettix (Vicar) on Apr 12, 2005 at 09:48 UTC
    Could you provide two-three lines of code demostrating your problem? Just to see if there's something wrong in how the comparison is inserted in the context.

    Flavio (perl -e "print(scalar(reverse('ti.xittelop@oivalf')))")

    Don't fool yourself.
Re: >= returning unexpected result
by ysth (Canon) on Apr 12, 2005 at 09:59 UTC
    Also try printing $value - $hash{'v1'} - $hash{'v2'} to see if one of the values is not exactly what you think.
      I will try that, thank you. Unfortunately since this occurs at random, it might be a while before I will actually get some output from it.
Re: >= returning unexpected result
by davecardwell (Initiate) on Apr 12, 2005 at 10:33 UTC

    Some more code, as requested:

    Retrieving the values (@grid is an array of array references retrieved from a mysql database with DBI). They are returned by reference and stuck in %dbdata:

    my %data = ( balance => $grid[0][0], overdraft => $grid[0][1], status => uc($grid[0][2]), );

    The following is part of a subroutine that is passed a bunch of parameters and then:

    my %data = @_; my $amount = $data{amount} ? $data{amount} : undef;

    Then the test:

    unless( $dbdata{balance}+$dbdata{overdraft} >= $amount ){ MyModule::Logger::log(BANK_ACCOUNT => "Debit FAILED user($self-> +{USER_ID}) reason($reason) amount($amount) because this failed: balan +ce($dbdata{balance})+overdraft($dbdata{overdraft})>=amount($amount)") +; return 0; }

    Example output:

    Debit FAILED user(<removed>) reason(ORDER_PAYMENT) amount(1742) becaus +e this failed: balance(1742)+overdraft(0)>=amount(1742)

      I find it surprising that money amounts would be stored as ints in the MySQL database.

      the lowliest monk

Re: >= returning unexpected result
by jbrugger (Parson) on Apr 12, 2005 at 10:33 UTC
    You're getting the values from a hash. Are they really numbers, or strings representing them?
    update After your last message, i see you get the data straight out of the database. Are the database fields (var)chars, text, blobs? -> there may be your problem.

    If strings, it's obvious it may go wrong sometimes.
    "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.
      Both are ints.