整数和浮点精度

时间:2009-12-15 12:29:47

标签: precision floating-accuracy

这更像是一个数值分析而不是编程问题,但我想你们中的一些人能够回答它。

在两个浮点数中,是否有任何精度损失?为什么呢?

在float和integer之和中,有没有精度丢失?为什么呢?

感谢。

9 个答案:

答案 0 :(得分:7)

  

在两个浮点数中,是否有任何精度丢失?

如果两个浮点数具有不同的幅度,并且两个都使用完整的精度范围(大约7个十进制数字),那么是的,你会看到最后一些地方有一些损失。

  

为什么?

这是因为浮点数以(符号)(尾数)×2 (指数)的形式存储。如果两个值具有不同的指数并且您添加它们,则较小的值将减少到尾数中的较少位数(因为它必须适应较大的指数):

PS> [float]([float]0.0000001 + [float]1)
1
  

在float和整数之和中,是否有任何精度丢失?

是的,正常的32位整数能够精确地表示不完全适合浮点数的值。浮动仍然可以存储大约相同的数字,但不再完全相同。当然,这仅适用于足够大的数字,即。即超过24位。

  

为什么?

因为float有24位精度,而且(32位)整数有32,所以float仍然可以保留幅度和大多数有效数字,但最后的位置可能会有所不同:

PS> [float]2100000050 + [float]100
2100000100

答案 1 :(得分:3)

精度取决于原始数字的大小。在浮点时,计算机在内部将数字312表示为科学记数法:

3.12000000000 * 10 ^ 2

左侧(尾数)的小数位数是固定的。指数也有上限和下限。这允许它代表非常大或非常小的数字。

如果您尝试添加两个幅度相同的数字,则结果在精度上应保持相同,因为小数点不必移动:

312.0 + 643.0 <==>

3.12000000000 * 10 ^ 2 +
6.43000000000 * 10 ^ 2
-----------------------
9.55000000000 * 10 ^ 2

如果您尝试添加非常大且非常小的数字,则会因为必须被挤入上述格式而失去精确度。考虑312 + 12300000000000000000000.首先,您必须缩放较小的数字以与较大的数字对齐,然后添加:

1.23000000000 * 10 ^ 15 +
0.00000000003 * 10 ^ 15
-----------------------
1.23000000003 <-- precision lost here!

浮点数可以处理非常大或非常小的数字。但它不能同时代表两者。

对于添加的int和double,int会立即变为double,然后适用。

答案 2 :(得分:2)

添加两个浮点数时,通常会出现一些错误。 D. Goldberg的"What Every Computer Scientist Should Know About Floating-Point Arithmetic"详细描述了效果和原因,以及如何计算误差的上限,以及如何推断更复杂计算的精确度。

将float添加到整数时,整数首先由C ++转换为float,因此添加了两个浮点数并引入错误的原因与上述相同。

答案 3 :(得分:1)

float的可用精度是有限的,因此当然存在任何给定操作都会降低精度的风险。

你的两个问题的答案都是“是”。

如果您尝试将非常大的浮点数添加到非常小的浮点数中,您将遇到问题。

或者,如果您尝试向float添加一个整数,其中整数使用的浮点数多于浮点数可用于其尾数。

答案 4 :(得分:1)

简短的回答:计算机代表一个位数有限的浮点数,通常用mantissa and exponent表示,因此只有几个字节用于有效数字,其他字节用于表示小数点的位置。

如果你试图添加(比方说)10 ^ 23和7,那么它将无法准确地表示该结果。添加float和integer时会应用类似的参数 - 整数将被提升为float。

答案 5 :(得分:1)

  

在两个浮点数中,是否有任何精度损失?   在float和integer之和中,是否有任何精度丢失?为什么呢?

并非总是如此。如果总和可以用您要求的精度表示,那么您将不会获得任何精度损失。

示例:0.5 + 0.75 =&gt;没有精确损失          x * 0.5 =&gt;没有精确损失(除非x太小)

在一般情况下,一个添加浮动的范围略有不同,因此精度损失实际上取决于舍入模式。 即:如果你要添加完全不同范围的数字,则需要精确度问题。

在极端情况下,非正规数会以牺牲CPU为代价来提供额外的精度。

根据编译器处理浮点计算的方式,结果可能会有所不同。

使用严格的IEEE语义,添加两个32位浮点数不应该提供比32位更好的精度。 在实践中,可能需要更多指令来确保,因此您不应该依赖于具有浮点的准确且可重复的结果。

答案 6 :(得分:0)

在两种情况下都是:

assert( 1E+36f + 1.0f == 1E+36f );
assert( 1E+36f + 1 == 1E+36f );

答案 7 :(得分:0)

case float + int与float + float相同,因为标准转换应用于int。在float + float的情况下,这是依赖于实现的,因为实现可以选择以双精度进行添加。当然,存储结果时可能会有一些损失。

答案 8 :(得分:0)

在这两种情况下,答案都是“是”。向int添加float时,无论如何都会在添加之前将整数转换为浮点表示。

为了理解原因,我建议你阅读这个宝石:What Every Computer Scientist Should Know About Floating-Point Arithmetic