4

当我尝试将大量数字存储到浮点数float varr = 123456789;中时,变量varr的值123456792.0不像123456789.0我预期的那样。为什么?

有什么解决办法吗?

我不能使用双精度或十进制,因为我在内存中被限制为 4 个字节。

4

4 回答 4

1

这是因为浮点变量的精度有限。改用双精度。

正如您在此处看到的,float 的精度仅为 7 位,而 double 的精度为 13:http: //msdn.microsoft.com/en-us/library/b1e65aza%28v=vs.80%29.aspx

使用四个字节的内存,您可以表达大约。40 亿个不同的值,即一个 9 位的十进制数。您必须问自己要显示的数字是否适合该范围。例如,如果您要存储从 0 到 999 999 999 的数字,则四个字节就足够了。如果您有从 1 000 000 000 到 1 999 999 999 的号码,那么它也足够了。在这种情况下,您需要通过减去 1 000 000 000 将输入数字(双精度数)转换为整数。读取值时,您可以执行逆运算。

可以将此原理扩展到显示其他数字范围或精度较低的更大范围。但是您必须自己编写转换代码。

于 2012-04-11T09:14:19.580 回答
1

如果您需要更高的精度,您可以使用doubledecimal
无论如何请记住,浮点数总是近似的。

于 2012-04-11T09:14:56.873 回答
0

如果您可以使用整数 ( int),以及 32 位整数(4 个字节),您可以存储该数字,并且不会遇到任何精度问题。

于 2012-04-11T10:26:29.800 回答
0

类型的精度float意味着这种限制。您可以改用double类型。

floatC# 中的 type 符合IEEE 754-2008 binary32 格式(单精度浮点格式)

来自维基百科

IEEE 754 标准将 binary32 指定为:

  • 符号位:1位
  • 指数宽度:8位
  • 有效精度:24(23 显式存储)

这给出了 6 到 9 位有效小数位的精度(如果将具有最多 6 个有效小数位的十进制字符串转换为 IEEE 754 单精度,然后转换回相同的有效小数位数,则最终字符串应与原始字符串匹配;和如果将 IEEE 754 单精度转换为具有至少 9 位有效小数的十进制字符串,然后再转换回单精度,则最终数字必须与原始数字匹配)。

符号位决定数字的符号,也是有效数的符号。Exponent 是从 −128 到 127(2 的补码)的 8 位有符号整数或从 0 到 255 的 8 位无符号整数,这是 IEEE 754 binary32 定义中公认的有偏形式。在这种情况下,指数值 127 表示实际为零。真有效位包括二进制点右侧的 23 个小数位和一个值为 1 的隐式前导位(二进制点左侧),除非指数以全零存储。因此,只有 23 位有效数位出现在内存格式中,但总精度为 24 位(相当于 log10(224) ≈ 7.225 个十进制数字)。

顺便说一句,我没有得到你的结果。我运行这段代码:

float varr = 123456789;
Console.WriteLine(varr.ToString("#"));

我的输出是123456800

于 2012-04-11T09:32:41.940 回答