4

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

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

在浮点数和整数的总和中,是否有任何精度损失?为什么?

谢谢。

4

9 回答 9

7

在两个浮点数的总和中,是否有任何精度损失?

如果两个浮点数的大小不同,并且都使用完整的精度范围(大约 7 个十进制数字),那么是的,您会在最后几个位置看到一些损失。

为什么?

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

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

在浮点数和整数的总和中,是否有任何精度损失?

是的,一个普通的 32 位整数能够准确地表示不完全适合浮点数的值。浮点数仍然可以存储大致相同的数字,但不再精确。当然,这只适用于足够大的数字,即。e. 长于 24 位。

为什么?

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

PS> [float]2100000050 + [float]100
2100000100
于 2009-12-15T12:33:03.813 回答
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!

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

至于添加整数和双精度数,整数会立即变成双精度数,然后上述适用。

于 2009-12-15T12:40:54.690 回答
2

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

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

于 2009-12-15T12:35:16.760 回答
1

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

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

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

或者,如果您尝试将整数添加到浮点数,其中整数使用的位数多于浮点数可用于其尾数的位数。

于 2009-12-15T12:33:22.910 回答
1

简短的回答:计算机表示一个具有有限位数的浮点数,这通常用尾数和指数来完成,因此只有几个字节用于有效数字,其他字节用于表示小数点的位置.

如果您尝试添加(例如)10^23 和 7,那么它将无法准确地表示该结果。添加浮点数和整数时也适用类似的论点——整数将被提升为浮点数。

于 2009-12-15T12:33:32.127 回答
1

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

不总是。如果总和可以用您要求的精度表示,并且您不会得到任何精度损失。

示例:0.5 + 0.75 => 没有精度损失 x * 0.5 => 没有精度损失(除非 x 太小)

在一般情况下,添加浮点数的范围略有不同,因此存在精度损失,这实际上取决于舍入模式。即:如果您要添加范围完全不同的数字,则会出现精度问题。

非正规在这里是为了在极端情况下以 CPU 为代价提供额外的精度。

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

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

于 2009-12-15T12:51:51.367 回答
0

在这两种情况下都是:

assert( 1E+36f + 1.0f == 1E+36f );
assert( 1E+36f + 1 == 1E+36f );
于 2009-12-15T12:32:31.957 回答
0

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

于 2009-12-15T12:35:07.087 回答
0

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

要了解原因,我建议您阅读这本瑰宝:每个计算机科学家都应该了解的浮点运算知识

于 2009-12-15T12:38:30.747 回答