c++floating-pointprecisionformat-specifiersuint64

Comparing int64 and float value does not work inside loop


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?


Solution

  • 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