c# - 使用 Convert.ToDecimal() 会导致 C# 中的值四舍五入。如何克服这个问题?

标签 c# optimization

Some_Variable 具有从数据库返回的值 295523.93。 [DataType: money (Transact-SQL数据类型,使用的数据库是SQL2005)]

  • (decimal)Some_Variable 给出值 = 295523.93 [DataType: decimal]
  • (float)Some_Variable 给出值 = 295523.938 [DataType: float]
  • (decimal)((float)Some_Variable) 给出值 = 295523.9 [DataType: decimal]
  • Convert.ToDecimal((float)Some_Variable) 给出值 = 295523.9 [数据类型:十进制] (
  • (decimal)((double)Some_Variable) 给出值 = 295523.93 [DataType: decimal]
  • Convert.ToDecimal((double)Some_Variable) 给出值 = 295523.93 [数据类型:十进制]

为什么下面在极少数情况下会给出 295523.9(自项目运行超过 2 年以来出现一次)

  • Convert.ToDecimal((float)Some_Variable) 给出值 = 295523.9 [数据类型:十进制]

我正在考虑使用 (decimal)Some_Variable,它给出的值 = 295523.93,但我想知道除了与数字在内存中的存储方式(二进制)相关之外是否还有任何解释?

[编辑]:虽然实际值来自数据库,但为了重现问题,我在下面的示例中直接为其分配了值。请在下面找到代码屏幕截图以及 Watch 窗口。 Code snippet to reproduce issue along with Watch window

最佳答案

float 具有极小的精度(对应于大约 7-8 位十进制数字)。例如,这些是您范围内的后续 float :

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

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

The Decimal value returned by this method contains a maximum of seven significant digits. If the value parameter contains more than seven significant digits, it is rounded using rounding to nearest.

295523.93 有八位有效数字。使用“舍入到最接近的值”舍入为七位有效数字得到 295523.9

关于c# - 使用 Convert.ToDecimal() 会导致 C# 中的值四舍五入。如何克服这个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19682133/

相关文章:

c# - 需要帮助将 Kendo TreeView 绑定(bind)到本地数据源

c# - 在添加SQL参数时使用null

C# 嵌套类/结构可见性

c# - SdkUtility.LaunchSignInPage 没有重定向到 ebay 登录页面

algorithm - 优化加权区间的总和

c++ - 简化/优化逻辑的工具?

r - 尝试使用投资组合分析进行优化时出错

c# - 使用 PushStreamContent 从 HTTPClient 上传

sql - 为什么创建不相关的索引会使我的查询更快?

c - OpenMP - 如何高效同步字段更新