-1

The question is really simple: consider two floats which are possibly not bitwise equal but difference is relatively small in all possible senses. Let's also assume that difference between their floors is smaller than some relatively small epsilon (0.01 should be definitely enough). Will their floors be bitwise equal (i.e. equal in terms of operator==)?

For example, will the code below return true all the time:

bool areRoundedFloatsEqual(float lhs, float rhs) {
    if (lhs > 0 && rhs > 0 && fabs(lhs - rhs) < 0.01) {
        lhs = std::floor(lhs);
        rhs = std::floor(rhs);

        if (fabs(lhs - rhs) < 0.5)
            return lhs == rhs;
    }

    return true;
}

In fact I'm interested in two questions:

  1. What will happen in the real life?
  2. What does standard say about it?

UPD There was incorrect example I replaced with description. (Thanks @MarcGlisse and
@KevinBallard for pointing at the error.)

UPD 2 Here is the topic which covers this problem pretty good: Representable result of floor() and ceil()

Community
  • 1
  • 1
anxieux
  • 757
  • 5
  • 14
  • Both versions can return false. – Marc Glisse Feb 13 '13 at 20:27
  • @MarcGlisse Why first can return false (if we suppose floating to int conversion succeeded)? – anxieux Feb 13 '13 at 20:29
  • @anxieux: If `lhs` is `9.999` and `rhs` is `10.001`, it'll get past the conditional but end up comparing `9 == 10`. – Lily Ballard Feb 13 '13 at 20:30
  • @KevinBallard Oh, really, wait a sec, I'll try to fix logic in original topic... – anxieux Feb 13 '13 at 20:31
  • @anxieux: I think you should explain in plain english what you want, instead of pasting a potentially-incorrect code sample. – Lily Ballard Feb 13 '13 at 20:33
  • Floating point value are very tricky, especially when you consider infinities, NaNs, denormals and negative zero. Also, floats can represent some numbers bigger than the maximum int value. Is it really worth to try to get all those corner cases right? – Trillian Feb 13 '13 at 20:41
  • @KevinBallard Updated topic. – anxieux Feb 13 '13 at 20:45
  • @Trillian Sometimes you have to compare floats, don't you? :) – anxieux Feb 13 '13 at 20:45
  • If their floors are equal, their floors will be bitwise equal. –  Feb 13 '13 at 20:54
  • @Sancho Why do you think so? – anxieux Feb 13 '13 at 20:56
  • @Sancho I meant "equal" in terms of fabs(a-b) < 0.0001 for example. Or whatever. Note, that std::floor returns float. – anxieux Feb 13 '13 at 20:59
  • So, not equal "in all possible senses", but only in the sense that their absolute difference is small? –  Feb 13 '13 at 21:03
  • @Sancho yes, sorry for confusion. – anxieux Feb 13 '13 at 21:04
  • `fabs(floor(a) - floor(b)) < 0.0001` only if `floor(a) == floor(b)`, as long as you're in the range of integers that doubles can accurately represent: http://stackoverflow.com/questions/605533/does-casting-to-an-int-after-stdfloor-guarantee-the-right-result –  Feb 13 '13 at 21:06

2 Answers2

2

fabs(floor(a) - floor(b)) < 0.0001 only if floor(a) == floor(b), as long as you're in the range of integers that doubles can accurately represent: Does casting to an int after std::floor guarantee the right result?

Community
  • 1
  • 1
  • 1
    Thanks, I also would link the following topic http://stackoverflow.com/questions/12592249/representable-result-of-floor-and-ceil – anxieux Feb 13 '13 at 21:14
0

floor (x) and ceil (x) are always integer values.

Any difference between two numbers floor or ceil (x) and floor or ceil (y) is the difference between two integer values, and therefore an integer.

The absolute value of such a difference is less than 1 if and only if both values are the same.

gnasher729
  • 51,477
  • 5
  • 75
  • 98