Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Unexpected results when storing a Math::Round nearest value in MongoDB

by Anonymous Monk
on May 16, 2013 at 16:25 UTC ( #1033863=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm calculating a risk score and rounding to the nearest ten-thousandth with Math::Round
my $score = 1 / $denominator; my $result = nearest(.0001, $score);
If I export the data with Spreadsheet::WriteExcel the value is displayed correctly in the worksheet.
PNA_Score 0.0928 0.1171 0.0563 0.0563 0.0895 0.0685
However, if I write the data to Mongo using the MongoDB module passing a hashref to insert I'm getting extra digits about 25% of the time:
> db.scores.find( {ScoreName: "PNA" }, {Score: 1}) { "_id" : ObjectId("5194e668f31ef5f450000097"), "Score" : 0.0928000000 +0000001 } { "_id" : ObjectId("5194e668f31ef5f450000099"), "Score" : 0.1171000000 +0000001 } { "_id" : ObjectId("5194e668f31ef5f45000009b"), "Score" : 0.0563 } { "_id" : ObjectId("5194e668f31ef5f45000009d"), "Score" : 0.2279000000 +0000002 } { "_id" : ObjectId("5194e668f31ef5f45000009f"), "Score" : 0.2689000000 +0000003 } { "_id" : ObjectId("5194e668f31ef5f4500000a1"), "Score" : 0.2535 } { "_id" : ObjectId("5194e668f31ef5f4500000a3"), "Score" : 0.1625 } { "_id" : ObjectId("5194e668f31ef5f4500000a5"), "Score" : 0.3165 }
Has anyone ran into this before?

Comment on Unexpected results when storing a Math::Round nearest value in MongoDB
Select or Download Code
Re: Unexpected results when storing a Math::Round nearest value in MongoDB
by MidLifeXis (Prior) on May 16, 2013 at 17:39 UTC

    what every programmer should know about floating point

    Update: IIRC, unless the denominator of your fraction is able to be represented as sums of powers of two (1/2 + 1/8, for example), you end up with an approximation of the value. Many times, this tends to be "close enough". If dealing with money, for example, you will often want to use some other representation than floating point under the hood (an integer representation of millicents or some such comes to mind).

    Update 2: As an example REPL - perl -ne 'printf("%.60f\n", $_)'.

    Update 3: See My floating point comparison does not work. Why ? for more information

    --MidLifeXis

Re: Unexpected results when storing a Math::Round nearest value in MongoDB
by hdb (Prior) on May 17, 2013 at 08:13 UTC

    If you paste "0.09280000000000001" into an Excel cell (Paste Special -> Text), Excel will forget the "0000000000001" part. So this is not a good test.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2014-12-27 10:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls