Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

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?

Replies are listed 'Best First'.
Re: Unexpected results when storing a Math::Round nearest value in MongoDB
by MidLifeXis (Monsignor) 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


Re: Unexpected results when storing a Math::Round nearest value in MongoDB
by hdb (Monsignor) 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?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1033863]
Approved by herveus
[Discipulus]: good morning nuns and monks!

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2018-06-21 07:04 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (117 votes). Check out past polls.