Question

I have an application that utilizes NHibernate to handle database functionality. Now I have a table with a column mapped as a float. NHibernate created the table in the MySql database, and I have validated the column to be "FLOAT" as well. NOTE: There is not FLOAT(M<,D) precision defined in the column, it's just "FLOAT".

Partial SQL table create statement:

CREATE TABLE `X` (
    `TresholdLow` float NOT NULL,

Now when I try to insert the domain model (POCO) with a float property of value 5.46, for example, all goes well, so the domain model is mapped properly and is working.

But when I try to insert the domain model with the property set at float.MinValue resulting in a value of 3.40282347E+38 I get the following error:

ERROR 1264: Out of range value for column 'TresholdLow' at row 1

I think it might have to do something with the following. This is input (marked by ?) and output of the immediate window in Visual Studio:

?float.MinValue.ToString();
"-3.402823E+38"
?float.MinValue
-3.40282347E+38

The first value IS accepted by MySQL, the latter ISN'T!!

How do I work around this issue? Practically it won't be a problem, but theoretically it is not so nice to have a database float column not accepting all possible float values coming from the application that is storing the data.

Was it helpful?

Solution

Since you report that -3.402823E+38 is accepted but -3.40282347E+38 is not, I speculate the problem is that some software is not rounding correctly.

The least finite IEEE-754 32-bit binary floating-point value is not –3.40282347E+38, since that is an approximation. The exact value is –340282346638528859811704183484516925440, which is slightly smaller in magnitude. For brevity, I will use M for –340282346638528859811704183484516925440.

–3.40282347E+38 is between the two representable values M and –infinity. According to the IEEE-754 rules for rounding to nearest, it ought to be rounded to M if it is closer to M than it is to the next value that would continue the finite pattern instead of jumping to infinity. Since –3.40282347E+38 is closer to M than it is to that next number, the result should be M.

However, people do not always write software that rounds correctly. It is conceivable that some software observes that –3.40282347E+38 exceeds M in magnitude and returns –infinity or a range error instead of rounding it correctly.

To work around the problem, I suggest trying -3.402823466E+38. This is less than M in magnitude but is close enough that it should round to exactly M.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top