2

I need to round a double to the nearest valid uint64_t.

So

uint64_t Round(double);
Round(std::numeric_limits<double>::max())==std::numeric_limits<uint64_t>::max();
Round(std::numeric_limits<double>::lowest())==std::numeric_limits<uint64_t>::min();
Round(1.1)==1;

The Round should be equivalent this to but for uint64_t rather than signed integral

auto Round(double d){
    std::fesetround(FE_TONEAREST);
    return llrint(d);
}

Are there any functions in std && boost to enable this?

Bomaz
  • 1,871
  • 1
  • 17
  • 22
  • How is rounding to the nearest `uint64_t` different from rounding to the nearest integer? The only thing I can think of is that it won't fit in a `uint64_t`, in which case you'd do, what, exactly?. – Scott Hunter Nov 29 '19 at 14:27
  • 2
    @ScottHunter That's covered in the first described test case: The maximum `double` (far larger than the maximum `uint64_t`) should round all the way down to the largest `uint64_t`. – Max Langhof Nov 29 '19 at 14:28

1 Answers1

2

A double cannot hold all the values of uint64_t, since both are usually 64-bits and the double needs to set aside bits for the exponent.

However, it's not too hard to get the closest value:

uint64_t Round(double x){
    double rounded=round(x);
    if(rounded<0)
        return 0;
    if(rounded>=pow(2,64))
       return std::numeric_limits<uint64_t>::max();
    return static_cast<uint64_t>(rounded);
}
Anthony Williams
  • 66,628
  • 14
  • 133
  • 155
  • Note that the overflow check isn't correct. [See here](https://stackoverflow.com/questions/526070/handling-overflow-when-casting-doubles-to-integers-in-c/30424410#30424410) for an explanation. – nwellnhof Nov 29 '19 at 14:35
  • `double` is usually 64 bit, but it could also have a different size. On some Arduinos for example it's 32 bit. – François Andrieux Nov 29 '19 at 14:44
  • Some implementations of `pow` are not good, so `pow(2, 64)` might not be correct. Alternatives include `0x1p64` in C++ 2017, `(UINT64_MAX/2+1) * 2.`, and `18446744073709551616.`. – Eric Postpischil Nov 30 '19 at 00:17