0

我有一个利用 NHibernate 处理数据库功能的应用程序。现在我有一个表,其中有一列映射为浮点数。NHibernate 在 MySql 数据库中创建了表,我也验证了该列是“FLOAT”。注意:列中没有定义 FLOAT(M<,D) 精度,它只是“FLOAT”。

部分SQL建表语句:

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

现在,例如,当我尝试插入具有值为 5.46 的浮点属性的域模型 (POCO) 时,一切顺利,因此域模型已正确映射并且正在工作。

但是,当我尝试插入属性设置float.MinValue为 3.40282347E+38 的域模型时,我收到以下错误:

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

我认为这可能与以下内容有关。这是 Visual Studio 中即时窗口的输入(用 ? 标记)和输出:

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

第一个值被 MySQL 接受,后者不接受!!

我该如何解决这个问题?实际上这不会是一个问题,但从理论上讲,让数据库浮点列不接受来自存储数据的应用程序的所有可能的浮点值并不是很好。

4

1 回答 1

1

由于您报告-3.402823E+38已接受但未接受-3.40282347E+38,因此我推测问题是某些软件未正确舍入。

最小有限 IEEE-754 32 位二进制浮点值不是 –3.40282347E+38,因为这是一个近似值。精确值为 –340282346638528859811704183484516925440,其数量级略小。为简洁起见,我将使用 M 表示 –340282346638528859811704183484516925440。

–3.40282347E+38 在两个可表示的值 M 和 –infinity 之间。根据 IEEE-754 舍入到最近的规则,如果它更接近于 M 比它更接近于将继续有限模式而不是跳到无穷大的下一个值,则应该舍入到 M。由于 –3.40282347E+38 与 M 的距离比与下一个数字的距离更近,因此结果应该是 M。

然而,人们并不总是编写能正确舍入的软件。可以想象,某些软件观察到 –3.40282347E+38 的大小超过 M 并返回 –infinity 或范围误差,而不是正确舍入。

为了解决这个问题,我建议尝试-3.402823466E+38. 这在数量级上小于 M,但足够接近以至于它应该精确地四舍五入到 M。

于 2013-09-16T15:56:04.730 回答