Here is my simple code.
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;
Input:
1 3
2 6
Output:
true
So I want to know that
static_cast<double>(a) / b == static_cast<double>(k * a) / (k * b)
is always true?
if not,
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;
is always print true
on input a
, b
, k * a
, k * b
to num1, num2, num3, num4?
Assuming IEEE-754 binary floating-point arithmetic is used with the round-to-nearest-ties-to-even rule, the comparison is true except in the cases below.
Given int
num1
, num2
, num3
, and num4
where num3
= k • num1
and num4
= k • num2
for some real number k, there are the following situations where static_cast<double>(num1) / num2 == static_cast<double>(num3) / num4
may evaluate to false:
num3
and num4
are both zero, either because num1
and num2
are zero or because k is zero. Then static_cast<double>(num3) / num4
evaluates to a NaN, and a NaN never compares equal to anything, not even to the same NaN.num2
is zero but num1
is not and k is negative. Then static_cast<double>(num1) / num2
evaluates to +∞ or −∞ according to whether num1
is positive or negative, while static_cast<double>(num3) / num4
evaluates to the opposite, −∞ or +∞ respectively, so the comparison evaluates to false.int
, excluding the sign bit, is wider than the significand of double
, the quotients may differ due to different roundings in the conversion to double
. For example, int
may be 64 bits while double
has a 53-bit significand. Suppose num1
is 253+1, num2
is 1, and k is 3, so num3
is 254+253+2+1 and num4
is 3. Then, due to rounding, static_cast<double>(num1)
produces 253, static_cast<double>(num3)
produces 254+253+4, and the divisions produce 253 and 253+2, which are not equal.num1
or k • num2
overflows the int
type, the comparison may evaluate to false.Other than in the cases above, the conversions to double
are exact, and the quotients are mathematically defined (do not have zero divisors) and are equal. In these cases, the rounding rule necessitates that the two divisions produce the same result, so the comparison evaluates to true.
Yes, you can get different answers; even when there are no NaN
/Infinity
etc. values are around. See Eric's fantastic answer as usual for the details. Here's a concrete counter-example to illustrate:
#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;
}
When run, this program produces:
k = 1097303040
a = 536913409
b = 2097152
lhs = 256.020264
rhs = -0.757798
equal: 0
Note that the results are not only not equal, they even have different signs!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With