gpt4 book ai didi

c# 更精确地打印浮点值

转载 作者:太空宇宙 更新时间:2023-11-03 18:03:20 24 4
gpt4 key购买 nike

我想以比默认值更高的精度打印 float 。

例如,当我从 float 打印 PI 的值时,我得到 6 位小数。但是,如果我将相同的值从 float 复制到 double 并打印它,我会得到 14 位小数。

为什么打印相同的值但作为 double 值时精度更高?

如何让 Console.WriteLine() 在打印 float 时输出更多小数而不需要先将其复制为 double 值?

我也试过 0.0000000000 但它并没有写得更精确,它只是添加了更多的零。 :-/

我的测试代码:

float x = (float)Math.PI;
double xx = x;
Console.WriteLine(x);
Console.WriteLine(xx);

Console.WriteLine($"{x,18:0.0000000000}"); // Try to force more precision
Console.WriteLine($"{xx,18:0.0000000000}");

输出:

3,141593
3,14159274101257
3,1415930000 <-- The program just added more zeroes :-(
3,1415927410

我还尝试在 https://www.h-schmidt.net/FloatConverter/IEEE754.html 输入 PI

PI的二进制 float 表示为0b01000000010010010000111111011011

因此值为:2 * 0b1.10010010000111111011011 = 2 * 1.57079637050628662109375 = 3.1415927410125732421875

所以有更多的小数可以输出。我如何让 C# 输出整个值?

最佳答案

float 不再精确。当您将其转换为 double 时,精度更差,即使精度(位数)增加了 - 基本上,您在 double print 中看到的所有额外数字是转换工件 - 它们错误,只是您可以在 double 中获得的给定 float 的最佳表示。这与二进制 float 的工作原理息息相关。

让我们看一下 float 的二进制表示:

01000000010010010000111111011100

第一位是符号,接下来的八位是指数,剩下的是尾数。当我们将它转​​换为 double 时我们会得到什么?指数保持不变,但尾数用零填充。但这实际上改变了数字 - 你得到 3.1415929794311523(四舍五入,与二进制 float 一样)而不是正确的 3.14159265358979 pi 的 double 值。您会产生精度更高的错觉,但这只是错觉 - 数字并不比以前更准确,您只是用噪声替换了零。

float 和 double 之间没有 1:1 的映射。相同的 float 值可以由许多不同的 double 值表示,数字的十进制表示也可以相应变化。如果您关心小数精度,则每次将 float 转换为 double 后都应进行舍入操作。请考虑以下代码:

double.Parse(((float)Math.PI).ToString())

我没有将 float 转换为 double ,而是首先将其更改为十进制表示形式(在字符串中),并从中创建了 double 。现在,您拥有的不是“截断的” double ,而是一个不存在额外精度的适当 double ;当你打印出来时,你会得到 3.1415930000。当然,仍然是四舍五入,因为它仍然是二进制 -> 十进制转换,但不再假装比实际精度更高 - 四舍五入发生在比浮点版本更晚的数字,零是真的 零,除了最后一个(仅近似为零)。

如果您想要真正的小数精度,您可能需要使用小数类型(例如 intdecimal)。 floatdouble 都是二进制 数,并且只有二进制精度。有限十进制数在二进制中不一定是有限的,就像有限三进制数在十进制中不一定是有限的(例如 1/3 没有有限十进制表示法)。

关于c# 更精确地打印浮点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42646654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com