Some_Variable的值是从数据库返回的295523.93。 [DataType:货币(Transact-SQL数据类型。使用的数据库为SQL2005)]


(十进制)Some_Variable给出值= 295523.93 [DataType:十进制]
(float)Some_Variable赋予值= 295523.938 [DataType:float]
(decimal)((float)Some_Variable)给出的值= 295523.9 [DataType:十进制]
Convert.ToDecimal((float)Some_Variable)给出值= 295523.9 [DataType:十进制]
[[decimal)((double)Some_Variable)给出值= 295523.93 [DataType:十进制]
Convert.ToDecimal((double)Some_Variable)给出值= 295523.93 [DataType:十进制]



为什么在极少数情况下(在项目运行超过2年后发生一次),以下内容给出295523.9?


Convert.ToDecimal((float)Some_Variable)给出值= 295523.9 [DataType:十进制]


我正在考虑使用(decimal)Some_Variable给出值= 295523.93,但是好奇是否除了它与数字如何存储在内存(二进制)相关之外还有其他解释?

[编辑]:虽然实际值来自数据库,但为了复制问题,我在下面的示例中直接为它分配了值。请在下面的代码屏幕快照以及“监视”窗口中找到。

最佳答案

float的精度非常小(对应于大约7-8个十进制数字)。例如,以下是您范围内的后续浮点数字:

01001000100100000100110001111101 --> 295523.90625
01001000100100000100110001111110 --> 295523.9375
01001000100100000100110001111111 --> 295523.96875


因此,例如295523.92的值将四舍五入为这些值中的第一个或第二个。由于第八位有效数字非常不准确,因此在转换为十进制时保留它毫无意义。 documentation of Convert.ToDecimal(float)中对此行为进行了描述(我强调):


  此方法返回的Decimal值最多包含七个有效数字。如果value参数包含七个以上的有效数字,则使用四舍五入到最接近的值四舍五入。


295523.93具有八个有效数字。使用“四舍五入到最接近”将四舍五入为七个有效数字。

09-25 21:30