Comparing int64 and float value does not work inside loop

103 views Asked by At

The following loop would run only when off which is uint64_t is less than the value returned by ceil which is double. However I don't see the loop being executed.

#include <bits/stdc++.h>
using namespace std;

int main()
{
    uint64_t offset = 1164226701485, size = 945, div = 10000;
    for (uint64_t off = offset / div; off < ceil((float)(offset + size) / div); off++)
    {
        cout<<off;
    }
                            
    return 0;
}

SO I tried printing those values which seems correct to me and the loop should have been executed atleast once

cout.precision(17);
cout<< offset / div<<" "<< ceil((float)(offset + size) / div);

Output:

116422670 116422672

I am not really sure what's happening here, how can I make the loop to execute?

2

There are 2 answers

8
Marek R On BEST ANSWER

Problem is this expression:

off < ceil((float)(offset + size) / div)

note that on one side of this comparation you have uint64_t on other float.

Before compare can be done common type has to be selected. It is a float.

So your value on the left: 116422670 is converted to float. Since float has only 6 significant digits, result is rounded to nearest value which can be represented in float.

It happens to be: 116422672f.

Demo: https://godbolt.org/z/xhEnMKE8e

It is hard to spot rounding issue when watching decimal value so take a look on this: https://godbolt.org/z/TTEqvx1vG

0
chux - Reinstate Monica On

how can I make the loop to execute?

Alternative to fixing floating point math: do not use floating point math for an integer problem.

In this case, use off scaled by div.

// for (uint64_t off = offset / div; off < ceil((float)(offset + size) / div); off++) {
//    cout<<off;
// }

for (uint64_t off = offset; off < offset + size; off += div)
    cout << off/div;
}