- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
该值为 2.01 和 2.52 之和除以 2 (2.01 + 2.52)/2
的结果。 Excel 将此值显示为 2.265,当格式化为 2 位数字时,它是 2.27。但是,文件中存储的值为 2.2649999999999997。当我重新创建这是 C# 时,我也在我的变量中得到了那个值,而不是 2.265。我知道这是由于 4.53 除以 2 的浮点精度问题。
double result = (2.01 + 2.52) / 2;
Console.WriteLine(result);
控制台显示 2.265,但 QuickWatch 调试器中显示的值显示 2.264999999999997。我怀疑在 WriteLine 方法中将值转换为字符串正在纠正浮点精度错误。
当我应用 Math.Round(result, 2, MidpointRounding.AwayFromZero)
时,返回的结果是 2.26
而不是 2.27
预期的。看起来它看起来像是我想要四舍五入的数字右边的第一个数字,看到它是 4 并忽略它右边的所有其他内容。问题是那些 9 只是因为精度问题而存在,需要包括在内,或者更好的是,该值应该是 2.265
。
我在代码中所做的是从 Excel 电子表格 "2.2649999999999997"
中读取文本值,将其转换为 double 2.264999999999999
,然后转换为字符串,这给了我 "2.265"
。然后,我将其转换回 double 2.265
,以便我可以对其应用 Math.Round
并获得 2.27
的预期结果。这是完整的代码:
double result = Convert.ToDouble(((2.01 + 2.52) / 2).ToString());
Console.WriteLine(Math.Round(result, 2, MidpointRounding.AwayFromZero));
我依靠 ToString 来清理浮点精度和舍入问题的方法是否正确?如果没有,我应该怎么做?
最佳答案
第一:题目很难。因为 4.53/2 = 2.265。这四舍五入为 2.27。然而,计算中导致较小结果 (2.264999999....) 的最小舍入误差将导致舍入为 2.26。这就是这里发生的事情。要解决这个问题,您需要有一个浮点算法,它具有与 Excel 相同的内部舍入误差。
来自这份文件https://en.wikipedia.org/wiki/Numeric_precision_in_Microsoft_Excel看起来好像 Excel 使用 IEEE 754 的修改 版本,而 C# 使用 IEEE 754。我不知道差异在哪里,但看起来好像 Excel 在内部生成不同的舍入错误。
本文档描述了差异:https://support.microsoft.com/en-us/kb/78113/en-us(例如,Excel 不使用非规范化数字。这意味着数字 < 2 的舍入误差有不同的行为)。
所以我假设你不能用“double”来解决这个问题
更新
但是,现在我明白问题不在于算术,而在于 Excel 显示数字的方式,也许这是一个解决方案
Math.Round(Math.Round(result, 3, MidpointRounding.AwayFromZero), 2, MidpointRounding.AwayFromZero)
第一轮到 3,然后到 2 位数。在我看来,Excel 正在执行此操作。
关于c# - 试图模仿 Excel 舍入让我很伤心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31278971/
我是一名优秀的程序员,十分优秀!