My function to get rid of fractional part of two doubles while retaining their ratio:
void enlarge(double &a, double &b)
{
while (a != trunc(a) || b != trunc(b))
{
a *= 10;
b *= 10;
//output added for debugging
cout << "a = " << a << ", b = " << b << endl;
cout << "trunc(a) = " << trunc(a) << ", trunc(b) = " << trunc(b) << endl;
cout << "a == trunc(a): " << to_string(a == trunc(a)) << ", b == trunc(b): " << to_string(b == trunc(b)) << endl;
//to see output step by step
string asd;
cin >> asd;
}
}
Output when it stops working correctly:
a = 0.876, b = 99.9
trunc(a) = 0, trunc(b) = 99
a == trunc(a): 0, b == trunc(b): 0
a
a = 8.76, b = 999
trunc(a) = 8, trunc(b) = 999
a == trunc(a): 0, b == trunc(b): 1
a
a = 87.6, b = 9990
trunc(a) = 87, trunc(b) = 9990
a == trunc(a): 0, b == trunc(b): 1
a
a = 876, b = 99900
trunc(a) = 876, trunc(b) = 99900 //This is where it stops working
a == trunc(a): 0, b == trunc(b): 1 //Notice how 876 != 876
a
a = 8760, b = 999000
trunc(a) = 8760, trunc(b) = 999000
a == trunc(a): 0, b == trunc(b): 1
What do I do in this situation?
The problem is that the original number wasn't exactly .876, although it wasn't much different. So you may have to multiply by 10 quite a few times to get it to be an integer.
Also, note that if the number was slightly smaller than .876, 1000 times the number would be slightly smaller than 876.0 and trunc(875.99999999...) is 875, not 876.
You might consider some threshold value where the number is "close enough" to an integer. for example, instead of using a==trunc(a)
, you could use the test
abs(a - round(a)) < 1e-6
Finally, if you wanted to be precise, you could multiply by 2 at each step, instead of by 10. You lose a little precision every time you multiply by 10, because 10 is not a power of 2. Multiplying by 2 will produce an integer after a maximum of 52 multiplications.