Problem with BSON_APPEND_DOUBLE

57 views
Skip to first unread message

Thành Khắc Nguyễn

unread,
Jun 1, 2017, 12:42:27 PM6/1/17
to BSON

Dear All
I got a problem when using bson_append_double. Here  is my sourcecode:
            dvalue = 0.01;
            bson_append_double(pbson, field_name, -1,(double)dvalue);

But the result when printed is annoying "key": 0.0099999997764825820923

Please help me with this, Thanks and Regards.

Evan Wies

unread,
Jun 1, 2017, 12:54:47 PM6/1/17
to bs...@googlegroups.com
Thành,

This is not a BSON issue.  What you are seeing is the limitations of storing floating point values.  0.01 cannot be stored exactly in a “double”.   You could printf with a format that will print it as 0.01 (e.g. "%0.2f”), but the number stored is still not exactly 0.01.

If you are new to this, search for “what every programmer should know about floating point”.  The seminal document is this link [1], but that search will bring up other useful links and guides too.

To get exact storage, you could use “fixed point”, meaning that there is some “implied” decimal place; for example storing 1.2345 as integer 12345 and 0.01 as integer 100.  There are other techniques, including storing string, but it all depends on what you are trying to do.

-Evan

--
You received this message because you are subscribed to the Google Groups "BSON" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bson+uns...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Evan

unread,
Jun 13, 2017, 1:43:10 AM6/13/17
to BSON
For people searching for this in the future.... I realized while doing some work with BSON today that I wasn't exactly right in my reply, and did some tests to confirm...

Applying double 0.01 works to many digits.   As this as this StackOverflow link (also by the OP) discusses, their problem is related to floating point conversion.

I made a simple test program illustrates.  Here's the output:

$ ./bson_float_test

double: 0.01000000000000000021

float:  0.00999999977648258209

{ "double" : 0.010000000000000000208, "float_cast" : 0.0099999997764825820923 }


Here's the test code :
/// cc -o bson_float_test bson_float_test.c  -lbson-1.0.0

#include <stdio.h>
#include <libbson-1.0/bson.h>

int main(int argc, const char* argv[])
{
    bson_t b
;
    bson_init
(&b);

   
double dvalue = 0.01;
    printf
("double: %0.20f\n", dvalue);
    bson_append_double
(&b, "double", -1, dvalue);

   
float fvalue = 0.01f;
    printf
("float:  %0.20f\n", fvalue);
    bson_append_double
(&b, "float_cast", -1, (double)fvalue);

   
char* json = bson_as_json(&b, NULL);
    printf
("%s\n", json);
    bson_free
(json);

   
return 0;
}



-Evan

To unsubscribe from this group and stop receiving emails from it, send an email to bson+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages