.net C语言中的双精度魔术#
这是一个非常简单的例子来演示浮点不精确性:.net C语言中的双精度魔术#,.net,.net,这是一个非常简单的例子来演示浮点不精确性: double a = 0.33; double b = 0.1; double c = a + b; printf("%.90f\n", c); // output: 0.430000000000000048849813083506887778639793395996093750000000000000000000000000000000000000 C#中的相同代码似乎会产生“C”的精确值: double a = 0.33;
double a = 0.33;
double b = 0.1;
double c = a + b;
printf("%.90f\n", c);
// output: 0.430000000000000048849813083506887778639793395996093750000000000000000000000000000000000000
C#中的相同代码似乎会产生“C”的精确值:
double a = 0.33;
double b = 0.1;
double c = a + b;
Console.WriteLine($"{c:N90}");
// output: 0.430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
在C#/dotNet端发生了什么?以下是我在VS2019中使用的代码
static class Program
{
static void Main(string[] args)
{
double a = 0.33;
double b = 0.1;
double c = a + b;
Console.WriteLine($"{"Format",-8} {"Value"}");
Console.WriteLine($"{"G",-8} {c:G}");
Console.WriteLine($"{"R",-8} {c:R}");
Console.WriteLine($"{"F40",-8} {c:F40}");
Console.WriteLine($"{"N40",-8} {c:N40}");
}
}
与输出
Format Value
G 0.43
R 0.43000000000000005
F40 0.4300000000000000000000000000000000000000
N40 0.4300000000000000000000000000000000000000
因此,即使存储的位值对应于0.43000000000000005
,显示过程也会从末尾循环一些位,以使数字更精确
0.43000000000000005 = 0b11111111011011100001010001111010111000010100011110101110000110
0.43000000000000000 = 0b11111111011011100001010001111010111000010100011110101110000101
差值是向下舍入的最后一位。这段逻辑必须隐藏在框架中double
的格式化函数中
更深入地了解一下,以下情况发生在CLR之外 调用中的以下函数将
双精度
转换为字符串
如您所见,它被标记为“代码>外部>代码”,这意味着它在基础C++库中调用非托管函数。
我会看到<代码> 0.4300万、48830830530697989697933、960937、3500、000万、000万、000万、000万、000亿,这是代码值>,这是更接近于C++的示例。此外,它的精度为15-17digits@PavelAnikhouski浮动80对浮动64可能?如果在调试版本中尝试,会得到什么结果?Pavel,我从调试器输出窗口复制了结果。您使用的代码与帖子中的代码相同吗?仅供参考-LinqPad5(.Net Framework)给出的代码0.430000000000000000000000000000000000000000
但LinqPad6(.Net核心)在同一台机器上给出0.43000000004884981308350688778639793395996093750000000000000000000000000000000000000000000000000000000000000000000
要获得c
的完整存储值(不舍入最后位),请使用c.ToString(“R”)