使用Convert.ToDecimal()会对C#中的值进行舍入。如何克服这个问题?

使用Convert.ToDecimal()会对C#中的值进行舍入。如何克服这个问题?,c#,optimization,C#,Optimization,某些_变量具有从数据库返回的值295523.93。[数据类型:货币(Transact-SQL数据类型。使用的数据库是SQL2005)] (十进制)某些_变量给出的值=295523.93[数据类型:十进制] (float)某些_变量给出的值=295523.938[数据类型:float] (十进制)((浮点)某些_变量)给出的值=295523.9[数据类型:十进制] Convert.ToDecimal((float)Some_变量)给出的值=295523.9[数据类型:十进制] ((十进制)((双

某些_变量具有从数据库返回的值295523.93。[数据类型:货币(Transact-SQL数据类型。使用的数据库是SQL2005)]

  • (十进制)某些_变量给出的值=295523.93[数据类型:十进制]
  • (float)某些_变量给出的值=295523.938[数据类型:float]
  • (十进制)((浮点)某些_变量)给出的值=295523.9[数据类型:十进制]
  • Convert.ToDecimal((float)Some_变量)给出的值=295523.9[数据类型:十进制] (
  • (十进制)((双精度)某些_变量)给出的值=295523.93[数据类型:十进制]
  • Convert.ToDecimal((双精度)某些_变量)给出的值=295523.93[数据类型:十进制]
为什么在极少数情况下(由于项目运行时间超过2年,因此发生一次),以下给出295523.9

  • Convert.ToDecimal((float)Some_变量)给出的值=295523.9[数据类型:十进制]
我正在考虑使用(十进制)某个给出值=295523.93的_变量,但很好奇除了它与数字如何存储在内存(二进制)中有关外,是否还有其他解释


[编辑]:虽然实际值来自数据库,但对于问题复制,我已在下面的示例中直接为其分配了值。请在代码屏幕截图下方以及观察窗口中查找。

float
的精度非常低(大约相当于7-8位小数)。例如,这些是您范围内的后续浮点数:

01001000100100000100110001111101 --> 295523.90625
01001000100100000100110001111110 --> 295523.9375
01001000100100000100110001111111 --> 295523.96875
因此,例如,
295523.92
的值将四舍五入到这些值中的第一个或第二个。由于第八个有效数字非常不准确,因此在转换为十进制时保留它是没有意义的。这种行为在(我强调)中描述:

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


295523.93
有八个有效数字。使用“四舍五入”将有效数字四舍五入到七个,产生
295523.9

您可能会感兴趣:某个变量的类型是什么?(值的编译时类型和执行时类型都很有用。)如果decimal导致了问题,您是否尝试过使用double?显示一些实际代码和关于这个神秘类型“Money”的详细信息这有助于回答这个问题。这是完全正常的。float类型的值只能存储7个有效数字。因此,只有2955239数字可以准确,其余的只是随机噪声数字。将float转换为decimal的隐式转换运算符知道这一点,并简单地去除噪声。这是c正确。因此,从
浮点
)或
十进制
的转换或转换不是内射映射,即使在
十进制
具有更高精度的域中也是如此。两个不同但“相近”的
float
值可以投影到相同的
decimal
。存在一个变通方法。@JeppeStigNielsen:正确,变通方法是,例如,
float.ToString(“r”)
,它输出一个“可以往返到相同数字的字符串”。