mysql2
mysql2 copied to clipboard
Prepared statement float value converted to 64bits ?
Hi,
When trying to switch to prepared_statements
, our float columns had different values in ruby (2.6 series).
For instance, 1.1 is now 1.100000023841858
I know that 1.100000023841858 is a limited floating point representation using 32bits.
I'm far from being an expert in C but when looking at the code, I've figured that a T_FLOAT is converted to as MYSQL_TYPE_DOUBLE in a case of a prepared statement
case T_FLOAT:
bind_buffers[i].buffer_type = MYSQL_TYPE_DOUBLE;
bind_buffers[i].buffer = xmalloc(sizeof(double));
*(double*)(bind_buffers[i].buffer) = NUM2DBL(argv[i]);
break;
But it's not handle the same way within a simple MySQL result
case MYSQL_TYPE_FLOAT: // float
val = rb_float_new((double)(*((float*)result_buffer->buffer)));
break;
case MYSQL_TYPE_DOUBLE: // double
val = rb_float_new((double)(*((double*)result_buffer->buffer)));
break;
At least, the buffer seems to be handled differently.
Also, I did a small change locally by switching my float
column to double
column and 1.1 stays 1.1.
Thanks for your time :)
Yes, this is an interesting case. MySQL's FLOAT column type is single-precision and DOUBLE is double-precision. Ruby doesn't have a single-precision floating point, so both are mapped to Ruby's Float which is double-precision.