C++ 精确除法会失去精度吗?
C++ will exact division lose precision?
Q1:一个整数除以它的约数会失去精度吗?
int a=M*N,b=N;//M and N are random non-zero integers.
float c=float(a)/b;
if (c==M)
cout<<"accurate"<<endl;
Q2:传递一个浮点值会失去精度吗?
float a=K;//K is a random float;
if (a==K)
cout<<"accurate"<<endl;
Q1:Will dividing a integer by its divisor lose precision ?
是的。我使用以下程序得出了一些数字:
#include <iostream>
#include <climits>
int main()
{
int M = 10;
int N = 7;
int inaccurateCount = 0;
for (; M < INT_MAX && inaccurateCount < 10; ++M )
{
int a = M*N;
float c = float(a)/N;
if ( c != M )
{
std::cout << "Not accurate for M: " << M << " and N: " << N << std::endl;
inaccurateCount++;
}
}
return 0;
}
这是输出:
Not accurate for M: 2396747 and N: 7
Not accurate for M: 2396749 and N: 7
Not accurate for M: 2396751 and N: 7
Not accurate for M: 2396753 and N: 7
Not accurate for M: 2396755 and N: 7
Not accurate for M: 2396757 and N: 7
Not accurate for M: 2396759 and N: 7
Not accurate for M: 2396761 and N: 7
Not accurate for M: 2396763 and N: 7
Not accurate for M: 2396765 and N: 7
Q2:Will passing a float value lose precision ?
不,不应该。
它并不准确,但要获得更准确的答案,您可以使用值类型 double 和 long
案例 1:是的,它在某些情况下会失去精度。对于较小的 M 值,它将是准确的。
情况 2:不,它不会丢失精度。
Q1:Will dividing a integer by its divisor lose precision ?
您实际上问过将 int
转换为 float
是否会丢失精度。
是的,它通常会这样做。在当今的 32 位(或更宽)计算机体系结构中,int
存储 32 位数据:1 位符号加上 31 位有效数。 float
也存储 32 位数据,但它们是:1 位符号、8 位指数和 23 位小数部分,参见。 IEEE 754 single-precision floating point format(它可能不会在 16 位架构上丢失精度,但我无法检查。)
根据浮点数的不同,它会以不同的表示形式存储,一种是归一化形式,其中小数部分前面加上一个隐藏的小数部分,这样,我们得到一个 24 位的有效数字。这小于存储在 int
.
中的值
例如整数 01010101 01010101 01010101 01010101
(二进制,space 只是为了更好的阅读)不能表示为 float
而不丢失精度。在规范化形式中,这将是 1,010101 01010101 01010101 01010101
* 2^30。所以我们在逗号后有 30 个有效位二进制数字,不能在不损失精度的情况下存储在 23 位(小数部分)中。实际的回合模式定义了如何缩短值。
请注意,它不取决于值是否实际 "high"。整数 01000000 00000000 00000000 00000000
是标准化形式 1,000000 00000000 00000000 00000000
* 2^30。此数字在逗号后有零有效位,可以在不丢失精度的情况下存储。
Q2: Will passing a float value lose precision ?
没有
Q1:Will dividing a integer by its divisor lose precision ?
如果 a
太大可能会降低精度,否则(如果 a
足够小可以精确表示为浮点数)则不会。当您转换 a
时,精度损失实际上可能已经发生。除法也会降低精度,但有时这些精度损失可能会相互抵消。
例如 N = 8388609
和 M=5
。您有(二进制)尾数 100...001 并与 101 相乘,最后得到 101000...0000101,但是最后两位将四舍五入为零并且您在 (float)(N*M ), 但是当你除以 5 时,你得到 1000...00 和 100 的余数,这意味着它应该四舍五入并得到原始数字。
Q2:Will passing a float value lose precision ?
不,它不会丢失精度。但是,您的代码仍可能无法将其识别为准确的。
如果 K
是 NaN
(例如 0.0/0.0
),那么 x
也会变成 NaN
-然而 NaN
不应该(需要)比较相等。在这种情况下,有人可能会争辩说你失去了精度,我同意,但并不是在 x=K
点失去了精度 - 你在生成 K
.
时已经失去了精度
Q1:一个整数除以它的约数会失去精度吗?
int a=M*N,b=N;//M and N are random non-zero integers.
float c=float(a)/b;
if (c==M)
cout<<"accurate"<<endl;
Q2:传递一个浮点值会失去精度吗?
float a=K;//K is a random float;
if (a==K)
cout<<"accurate"<<endl;
Q1:Will dividing a integer by its divisor lose precision ?
是的。我使用以下程序得出了一些数字:
#include <iostream>
#include <climits>
int main()
{
int M = 10;
int N = 7;
int inaccurateCount = 0;
for (; M < INT_MAX && inaccurateCount < 10; ++M )
{
int a = M*N;
float c = float(a)/N;
if ( c != M )
{
std::cout << "Not accurate for M: " << M << " and N: " << N << std::endl;
inaccurateCount++;
}
}
return 0;
}
这是输出:
Not accurate for M: 2396747 and N: 7
Not accurate for M: 2396749 and N: 7
Not accurate for M: 2396751 and N: 7
Not accurate for M: 2396753 and N: 7
Not accurate for M: 2396755 and N: 7
Not accurate for M: 2396757 and N: 7
Not accurate for M: 2396759 and N: 7
Not accurate for M: 2396761 and N: 7
Not accurate for M: 2396763 and N: 7
Not accurate for M: 2396765 and N: 7
Q2:Will passing a float value lose precision ?
不,不应该。
它并不准确,但要获得更准确的答案,您可以使用值类型 double 和 long
案例 1:是的,它在某些情况下会失去精度。对于较小的 M 值,它将是准确的。
情况 2:不,它不会丢失精度。
Q1:Will dividing a integer by its divisor lose precision ?
您实际上问过将 int
转换为 float
是否会丢失精度。
是的,它通常会这样做。在当今的 32 位(或更宽)计算机体系结构中,int
存储 32 位数据:1 位符号加上 31 位有效数。 float
也存储 32 位数据,但它们是:1 位符号、8 位指数和 23 位小数部分,参见。 IEEE 754 single-precision floating point format(它可能不会在 16 位架构上丢失精度,但我无法检查。)
根据浮点数的不同,它会以不同的表示形式存储,一种是归一化形式,其中小数部分前面加上一个隐藏的小数部分,这样,我们得到一个 24 位的有效数字。这小于存储在 int
.
例如整数 01010101 01010101 01010101 01010101
(二进制,space 只是为了更好的阅读)不能表示为 float
而不丢失精度。在规范化形式中,这将是 1,010101 01010101 01010101 01010101
* 2^30。所以我们在逗号后有 30 个有效位二进制数字,不能在不损失精度的情况下存储在 23 位(小数部分)中。实际的回合模式定义了如何缩短值。
请注意,它不取决于值是否实际 "high"。整数 01000000 00000000 00000000 00000000
是标准化形式 1,000000 00000000 00000000 00000000
* 2^30。此数字在逗号后有零有效位,可以在不丢失精度的情况下存储。
Q2: Will passing a float value lose precision ?
没有
Q1:Will dividing a integer by its divisor lose precision ?
如果 a
太大可能会降低精度,否则(如果 a
足够小可以精确表示为浮点数)则不会。当您转换 a
时,精度损失实际上可能已经发生。除法也会降低精度,但有时这些精度损失可能会相互抵消。
例如 N = 8388609
和 M=5
。您有(二进制)尾数 100...001 并与 101 相乘,最后得到 101000...0000101,但是最后两位将四舍五入为零并且您在 (float)(N*M ), 但是当你除以 5 时,你得到 1000...00 和 100 的余数,这意味着它应该四舍五入并得到原始数字。
Q2:Will passing a float value lose precision ?
不,它不会丢失精度。但是,您的代码仍可能无法将其识别为准确的。
如果 K
是 NaN
(例如 0.0/0.0
),那么 x
也会变成 NaN
-然而 NaN
不应该(需要)比较相等。在这种情况下,有人可能会争辩说你失去了精度,我同意,但并不是在 x=K
点失去了精度 - 你在生成 K
.