这是我的简单代码。
int num1, num2;
cin >> num1 >> num2;
int num3, num4;
cin >> num3 >> num4;
double result1 = static_cast<double>(num1) / num2;
double result2 = static_cast<double>(num3) / num4;
cout.setf(ios::boolalpha);
cout << (result1 == result2) << endl;
输入:
1 3
2 6
输出:
true
所以我想知道
static_cast<double>(a) / b == static_cast<double>(k * a) / (k * b)
总是真的吗?
如果没有,
int num1, num2;
cin >> num1 >> num2;
int num3, num4;
cin >> num3 >> num4;
int gcd1 = gcd(num1, num2);
int gcd2 = gcd(num3, num4);
double result1 = static_cast<double>(num1 / gcd1) / (num2 / gcd1);
double result2 = static_cast<double>(num3 / gcd2) / (num4 / gcd2);
cout.setf(ios::boolalpha);
cout << (result1 == result2) << endl;
总是在输入true
,a
,b
,k * a
上将k * b
打印到num1,num2,num3,num4吗?
答案 0 :(得分:7)
假设将IEEE-754二进制浮点算法与舍入到最近的关系到偶数规则一起使用,除以下情况外,该比较为真。
给出int
num1
,num2
,num3
和num4
,其中num3
= k •{ {1}}和num1
= k •num4
对于某个实数 k ,在以下情况下,num2
可能评估为假:
static_cast<double>(num1) / num2 == static_cast<double>(num3) / num4
和num3
均为零,或者是因为num4
和num1
为零,或者是因为 k 为零。然后num2
得出一个NaN,一个NaN绝不等于任何东西,甚至不等于相同的NaN。static_cast<double>(num3) / num4
为零,但num2
不是零, k 为负。然后,num1
根据static_cast<double>(num1) / num2
是正还是负来求值为+∞或-∞,而num1
则求出相反的值,分别为-∞或+∞,因此比较的结果为false 。static_cast<double>(num3) / num4
(不包括符号位)宽于int
的有效位数时,由于转换为double
时舍入的原因不同,商可能会不同。例如,double
可以为64位,而int
的有效位数为53位。假设double
是2 53 +1,num1
是1, k 是3,所以num2
是2 54 +2 53 + 2 + 1且num3
为3。然后,由于舍入,num4
产生2 53 , static_cast<double>(num1)
产生2 54 +2 53 +4,除法产生2 53 和2 53 +2,不相等。static_cast<double>(num3)
或 k •num1
溢出num2
类型,则比较结果可能为false 。除上述情况外,到int
的转换是精确的,并且商是数学定义的(不具有零除数)且相等。在这种情况下,四舍五入规则要求两个除法必须产生相同的结果,因此比较结果为true。
答案 1 :(得分:2)
是的,您可以获得不同的答案;即使没有NaN
/ Infinity
等值,也仍然存在。有关详细信息,请照常查看Eric出色的解答。这是一个具体的反例来说明:
#include <stdint.h>
#include <stdio.h>
int main()
{
int32_t k = 1097303040;
int32_t a = 536913409;
int32_t b = 2097152;
double lhs = static_cast<double>(a) / b;
double rhs = static_cast<double>(k*a) / (k*b);
printf ("k = %d\n", k);
printf ("a = %d\n", a);
printf ("b = %d\n", b);
printf ("lhs = %f\n", lhs);
printf ("rhs = %f\n", rhs);
printf ("equal: %d\n", lhs == rhs);
return 0;
}
运行时,此程序将产生:
k = 1097303040
a = 536913409
b = 2097152
lhs = 256.020264
rhs = -0.757798
equal: 0
请注意,结果不仅不相等,甚至有不同的符号!
答案 2 :(得分:0)
让我们假设当今通常的实现方式:
int
是32位double
是64位二进制浮点数对于这些,两者始终都是正确的,因为:
int
可以转换为double
而不会造成任何精度损失。false
。请注意,仅当您的程序不包含未定义行为时,这才是正确的。例如,如果您的程序包含零除,可能会发生这种情况。在这种情况下,您的比较可能会导致错误。否则会生成系统异常(因此根本不会执行比较)。