mastercoin-MSC / mastercore

mastercore info
mastercoin.org
MIT License
24 stars 11 forks source link

Be aware of roundtouint64 (!) #178

Closed dexX7 closed 9 years ago

dexX7 commented 9 years ago
uint64_t rounduint64(double d)
{
  return (uint64_t)(abs(0.5 + d));
}

Range:

... turned out to clip pretty fast and it's only possible to use numbers in the range of signed ints.

2147483648.0 (that is INT32_MAX + 1) and any other number greater than INT32_MAX yield for me a result of 18446744071562067968.

Overflow:

Say MAX is the the maximum of an accepted range and rounduint64(MAX) is called, then 0.5 + MAX will result in an overflow, because 0.5 + MAX is greater than MAX.

Negative numbers:

The results for positive numbers seem to be fine and anything greater or equal than .5 is rounded up:

rounduint64(0.00000000) -> 0
rounduint64(1.00000000) -> 1
rounduint64(2.00000000) -> 2
rounduint64(3.00000000) -> 3

rounduint64(0.49999999) -> 0
rounduint64(1.49999999) -> 1
rounduint64(2.49999999) -> 2
rounduint64(3.49999999) -> 3

rounduint64(0.50000000) -> 1
rounduint64(1.50000000) -> 2
rounduint64(2.50000000) -> 3
rounduint64(3.50000000) -> 4

rounduint64(0.50000001) -> 1
rounduint64(1.50000001) -> 2
rounduint64(2.50000001) -> 3
rounduint64(3.50000001) -> 4

But what about negative numbers?

rounduint64(-0.00000000) -> 0
rounduint64(-1.00000000) -> 0
rounduint64(-2.00000000) -> 1
rounduint64(-3.00000000) -> 2

rounduint64(-0.49999999) -> 0
rounduint64(-1.49999999) -> 0
rounduint64(-2.49999999) -> 1
rounduint64(-3.49999999) -> 2

rounduint64(-0.50000000) -> 0
rounduint64(-1.50000000) -> 1
rounduint64(-2.50000000) -> 2
rounduint64(-3.50000000) -> 3

rounduint64(-0.50000001) -> 0
rounduint64(-1.50000001) -> 1
rounduint64(-2.50000001) -> 2
rounduint64(-3.50000001) -> 3

Is this expected behavior?