矛盾在C#中四舍五入的实数 [英] Inconsistency rounding real numbers in C #

查看:211
本文介绍了矛盾在C#中四舍五入的实数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个测试code:

I have this test code:

class Test
{
    static void Main()
    {
        decimal m = 1M / 6M;
        double d = 1.0 / 6.0;

        decimal notQuiteWholeM = m + m + m + m + m + m; // 1.0000000000000000000000000002M
        double notQuiteWholeD = d + d + d + d + d + d;   // 0.99999999999999989

        Console.WriteLine(notQuiteWholeM); // Prints: 1.0000000000000000000000000002
        Console.WriteLine(notQuiteWholeD); // Prints: 1.

        Console.WriteLine(notQuiteWholeM == 1M);  // False
        Console.WriteLine(notQuiteWholeD < 1.0);   // Prints: True. Why?

        Console.ReadKey();
    }
}

为什么这一行打印1?

Why this line prints 1?

Console.WriteLine(notQuiteWholeD); // Prints: 1

这是这一个,为什么打印true?

an this one, why prints True?

有一个自动取整处理?我能做些什么来打印的正确/计算的价值呢?

Is there an automatically rounding process? What can I do to print the correct/calculated value?

[注意:我发现这个例子code中的在Nutsheel 30页C#5.0:实数舍入误差。

[Note: I found this example code in C# 5.0 in a Nutsheel page 30: Real Number Rounding Error].

在此先感谢。

推荐答案

不太读同样的方式你的问题与其他两个答案。它的要点:是否重新presentation一个圆圆在C#

Not quite reading your question in the same way as the other two answers. The gist of it: Does the formatted string representation of a double "round" in C#?

是的。

在内部重新$ P $

Internally double is represented with full IEEE-754 decimal digit precision (15-17 digits), which is why:

notQuiteWholeD < 1.0 == true    // because notQuiteWholeD = 0.99999999999999989

然而的,当格式化为一个字符串,默认情况下它会使用15位的precision - 相当于:

However, when formatting it as a string, by default it will use 15 digit precision - equivalent to:

String.Format("{0:G15}", notQuiteWholeD)   // outputs "1"

要获得完整的内部重新presentation所有的数字,你可以使用:

To get all the digits of the full internal representation, you can use:

Console.WriteLine("{0:G17}", notQuiteWholeD);

或者

Console.WriteLine("{0:R}", notQuiteWholeD);

两者,在这种情况下,将输出0,99999999999999989

Both, in this case, will output "0,99999999999999989".

,前者将始终使用17位的precision。后者(往返precision)将使用15个数字,如果这就够了precision以下是真实的,否则它会使用17:

The former will always use 17 digit precision. The latter ("roundtrip precision") will use 15 digits if that's enough precision for the following to be true, otherwise it will use 17:

Double.Parse(String.Format("{0:G15}", notQuiteWholeD)) == notQuiteWholeD

红利示例: ......当 G17 研究不同:

Bonus Example: ... of when G17 and R differ:

Console.WriteLine("{0:G17}", 1.0000000000000699); // outputs "1.0000000000000699"
Console.WriteLine("{0:R}",   1.0000000000000699); // outputs "1.00000000000007"

1.0000000000000699(17显著位)可以重新presented得足够准确,仅使用15显著数字往返。换句话说,在重新presentation 1.00 ... 07 是相同 1.00 ... 0699

1.0000000000000699 (17 significant digits) can be represented accurately enough for a roundtrip using only 15 significant digits. In other words, the double representation of 1.00...07 is the same as for 1.00...0699.

所以 1.00 ... 07 (15位)是一个更短的投入,得到完全相同的内部(17位),再presentation。这意味着研究将它舍入到15位,而 G17 将保持内部重新$ P $的所有数字psentation。

So 1.00...07 (15 digits) is a shorter input to get the exact same internal (17 digit) representation. That means R will round it to 15 digits, while G17 will keep all the digits of the internal representation.

也许是意识到这个时候更清晰

Maybe it's clearer when realizing that this:

Console.WriteLine("{0:G17}", 1.00000000000007); // outputs "1.0000000000000699"
Console.WriteLine("{0:R}",   1.00000000000007); // outputs "1.00000000000007"

...给出同样的结果。

... gives the exact same results.

这篇关于矛盾在C#中四舍五入的实数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆