0

如果我将值 0.1 分配给浮点数:

float f = 0.1;

存储在内存中的实际值并不是 0.1 的精确表示,因为 0.1 不是一个可以用单精度浮点格式精确表示的数字。存储的实际值(如果我的数学运算正确的话)是

0.100000001490116119384765625

但我无法确定让 C# 打印出该值的方法。即使我要求它将数字打印到很多小数位,它也没有给出正确的答案:

// prints 0.10000000000000000000000000000000000000000000000000
Console.WriteLine(f.ToString("F50"));

如何打印存储在浮点数中的确切值;内存中位模式实际表示的值?

编辑:在其他地方引起了我的注意,您可以在 .NET Core 和 .NET 5.0 上获得我要求使用标准格式字符串的行为。所以这个问题是.NET Framework 特有的,我猜。

4

3 回答 3

0

对于 .NET Framework,使用格式字符串G。不完全是,但足以解决浮动错误。

> (0.3d).ToString("G70")
0.29999999999999999
> (0.1d+0.2d).ToString("G70")
0.30000000000000004
于 2021-12-07T14:04:36.113 回答
0

糟糕,这个答案与 C 相关,而不是 C#。

保留它,因为它可能提供 C# 洞察力,因为语言在这方面有相似之处。


如何打印存储在浮点数中的确切值?

// Print exact value with a hexadecimal significant.
printf("%a\n", some_float);
// e.g. 0x1.99999ap-4 for 0.1f

要打印 afloat的十进制值,并与所有其他 具有足够独特的小数位float

int digits_after_the_decimal_point = FLT_DECIMAL_DIG - 1;  // e.g. 9 -1
printf("%.*e\n", digits_after_the_decimal_point, some_float);
// e.g. 1.00000001e-01 for 0.1f

打印所有小数位的十进制值是困难的 - 并且很少需要。代码可以使用更高的精度。超过某个点(例如 20 位有效数字),big_value可能会失去低位数字的正确性printf()这种错误在 C 和IEEE 754中是允许的:

int big_value = 19; // More may be a problem.
printf("%.*e\n", big_value, some_float);
// e.g. 1.0000000149011611938e-01 for 0.1f
// for FLT_TRUE_MIN and big_value = 50, not quite right
// e.g. 1.40129846432481707092372958328991613128026200000000e-45

要打印所有小数位的十进制值float,请编写一个辅助函数。 例子

// Using custom code
// -FLT_TRUE_MIN 
-0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125
于 2021-08-30T15:23:39.077 回答
-3

您应该使用小数而不是浮点数,如下所示:

decimal f = 0.1m;

它只会打印 0.1。

您可以查看此答案以了解浮点数、双精度和小数之间的区别

.NET 中十进制、浮点和双精度的区别?

于 2021-08-28T19:42:14.893 回答