当我尝试将大量数字存储到浮点数float varr = 123456789;
中时,变量varr
的值123456792.0
不像123456789.0
我预期的那样。为什么?
有什么解决办法吗?
我不能使用双精度或十进制,因为我在内存中被限制为 4 个字节。
当我尝试将大量数字存储到浮点数float varr = 123456789;
中时,变量varr
的值123456792.0
不像123456789.0
我预期的那样。为什么?
有什么解决办法吗?
我不能使用双精度或十进制,因为我在内存中被限制为 4 个字节。
这是因为浮点变量的精度有限。改用双精度。
正如您在此处看到的,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 将输入数字(双精度数)转换为整数。读取值时,您可以执行逆运算。
可以将此原理扩展到显示其他数字范围或精度较低的更大范围。但是您必须自己编写转换代码。
如果您可以使用整数 ( int
),以及 32 位整数(4 个字节),您可以存储该数字,并且不会遇到任何精度问题。
类型的精度float
意味着这种限制。您可以改用double
类型。
float
C# 中的 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
。