develooper Front page | perl.perl5.porters | Postings from May 2015

[perl #125266] Unexpected interaction between binary multiplication operator and Test::More::cmp_ok()

Thread Previous | Thread Next
From:
James E Keenan
Date:
May 28, 2015 14:22
Subject:
[perl #125266] Unexpected interaction between binary multiplication operator and Test::More::cmp_ok()
Message ID:
rt-4.0.18-12689-1432822922-48.125266-75-0@perl.org
# New Ticket Created by  James E Keenan 
# Please include the string:  [perl #125266]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=125266 >


Today I was bitten by an unexpected interaction between Perl's binary multiplication operator (*) and Test::More::cmp_ok().  I got expected results only on very old versions of Perl and Test::More.  Though I was able to compensate for this problem on newer versions of Perl and Test::More, the fact that I got unexpected results suggests either the presence of a bug or the need for some cautionary documentation somewhere.

The situation:  I needed to test whether I was getting expected values of prices stored in US dollars (USD) but converted to Japanese yen (JPY).  For testing purposes, I assumed that the JPY/USD exchange rate was 8:1.

Consider the program attached, 'cmp_ok.pl', which illustrates four different usages of Test::More::cmp_ok().  Cet. par., I would expect all four to PASS and, when run with perl-5.6.2 and the version of Test::More that came with that perl, 0.47, the do.

#####
$ perlbrew switch perl-5.6.2
$ perl cmp_ok.pl 
ok 1 - Perl version:       5.006002
ok 2 - Test::More version: 0.47
ok 3 - Use Test::More::cmp_ok() to compare two floats
ok 4 - Both floats explicitly assigned; compare with '=='
ok 5 - Both floats explicitly assigned; compare with 'eq'
ok 6 - One float explicitly assigned, one calculated via '*'; compare with '=='
ok 7 - One floatexplicitly assigned, one calculated via '*' then sprintf-ed; compare with '=='
1..7
#####

However, when I switch to perl-5.8.9 and the version of Test::More that came with that perl, 0.80, the third test FAILs.  In the third test, I calculate the expected JPY price by multiplying the USD price by the JPY/USD exchange rate -- multiplication of two floats -- and assign the result to $calculated_jpy, which I then use in the next instance of 'cmp_ok'.  The output of 'cmp_ok' suggests that the two values are not mathematically equal even though the 'got' and 'expected' outputs are identical!

$ perlbrew switch perl-5.8.9
$ perl cmp_ok.pl 
ok 1 - Perl version:       5.008009
ok 2 - Test::More version: 0.8
ok 3 - Use Test::More::cmp_ok() to compare two floats
ok 4 - Both floats explicitly assigned; compare with '=='
ok 5 - Both floats explicitly assigned; compare with 'eq'
not ok 6 - One float explicitly assigned, one calculated via '*'; compare with '=='
#   Failed test 'One float explicitly assigned, one calculated via '*'; compare with '==''
#   at cmp_ok.pl line 20.
#          got: 1.68
#     expected: 1.68
ok 7 - One floatexplicitly assigned, one calculated via '*' then sprintf-ed; compare with '=='
1..7
# Looks like you failed 1 test of 7.
#####

Testing on more recent perl/Test::More combinations, I get the same results as I did on 5.8.9/0.80.  Example:

#####
$ perlbrew switch perl-5.20.1
$ perl cmp_ok.pl 
ok 1 - Perl version:       5.020001
ok 2 - Test::More version: 1.001002
ok 3 - Use Test::More::cmp_ok() to compare two floats
ok 4 - Both floats explicitly assigned; compare with '=='
ok 5 - Both floats explicitly assigned; compare with 'eq'
not ok 6 - One float explicitly assigned, one calculated via '*'; compare with '=='
#   Failed test 'One float explicitly assigned, one calculated via '*'; compare with '==''
#   at cmp_ok.pl line 20.
#          got: 1.68
#     expected: 1.68
ok 7 - One floatexplicitly assigned, one calculated via '*' then sprintf-ed; compare with '=='
1..7
# Looks like you failed 1 test of 7.
#####

Note that when I sprintf-ed the product of the multiplication and used the result in 'cmp_ok', I got the expected PASS (fourth instance in each perl version).

I haven't yet had time to figure out whether the change in behavior between 5.6.2/0.47 and 5.8.9/0.80 occurred in perl or in Test::More.  But I suspect that this surprising behavior needs to be documented somewhere.

Recommendations?

Thank you very much.
Jim Keenan
James E Keenan (jkeenan@cpan.org)
Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About