Incorrect float values returned via Node driver
Description
Environment
Running on:
Mac OSX 10.12.5
Node.js version 7.8.0
cassandra-driver 3.2.2.
Pull Requests
Affects versions
Fix versions
Activity

Jorge Bay Gondra July 6, 2017 at 8:33 AM
The Node.js driver representation of the C* float values (binary32) into JavaScript double (binary64) is accurate and there is no loss of information.
Note that the string representation of the float value in CQLSH / Python, Java or JavaScript is not exact: when converting a float/double value to string, it outputs enough decimal digits to be converted back to the same value. There are several mismatches when trying to deal with float/double approximations of an arbitrary precision decimal (a famous one is 0.3 != (0.2 + 0.1)
) and you should choose your datatypes accordingly.
If you need an exact arbitrary-precision decimal representation of the value, use decimal
(ie: financial computations). If you want a more compact binary representation, which arithmetic operations run faster and don't mind the lack of accurate decimal representation, use double
/float
.

Andy Tolbert July 5, 2017 at 7:21 PM
Hi , I'm a bit on the fence about whether or not it should handle it. In general, it is not a good idea to use IEEE 754 (float/double) values where precision could be lost from rounding (i.e. financial/scientific applications). Things gets muddied up further by the fact that javascript doesn't have a way to represent float as a 4 byte IEEE 754 value so there will be a precision difference here.
To help me understand better, what is the use case for using float instead of decimal? If you don't need exact precision, then couldn't you use something like toFixed
? On the other hand if you do need exact precision, you should be using decimal.

Gim Mahasintunan July 5, 2017 at 5:50 PM
Hi Andy,
Thanks for the detailed reply. Sorry for the slow response, I was OOO for a few days there.
I think consumers of the C* driver would expect the same value to be returned regardless of driver or underlying peculiarities of JS (of which, there are many). In some instances, we can't change the schema type to decimal.
That's really great that the nodejs-driver provides a BigDecimal implementation. Any chance the driver be enhanced to provide a Float implementation as well? Perhaps if there's a way to cast the query to return a String value, then the driver could then call parseFloat before returning the result.
Would love to hear your thoughts.
Thanks!

Andy Tolbert June 29, 2017 at 9:01 PM
Hi , I believe this is happening because javascript numbers are double-precision 64-bit IEEE 754 values but a float in cassandra is 32-bit precision IEEE 754 value (like it is in java).
Because of this, when the nodejs-driver parses the float, it is parsing a 32-bit value into 64-bit precision type. This explains why the number you get back is different than you anticipate.
If you were to try the following in java with the java driver (storing a 32-bit value (float) in a 64-bit type (double)), you would get a similar result:
yields:
If this matters, it might be best to consider using the cql decimal type. The nodejs-driver provides its own BigDecimal
implementation.
Details
Details
Assignee
Reporter

I'm encountering an issue where float values aren't being returned correctly by the Node.js driver. Note, I did try with the Java driver and that worked fine just for comparison.
Recreation instructions are included below. Setting a float value to 0.33 via cqlsh looks fine on the commandline, but when returned by the driver I get 0.33000001311302185. This is a major issue for us.
Please let me know if you need any additional info. Thanks!