2

I have the following code:

 @property (nonatomic, assign) CGFloat floatValue;

--

 if (floatValue)
 {
    //Do something
 }

Since Xcode 7 - compiler error occurs :

Implicit conversion turns floating-point number into integer: 'CGFloat' to 'bool'

Can anyone explain what is going / suggest code edits to rectify

Ronald Palmer
  • 111
  • 1
  • 7
  • So it appears from answers below that Apple is trying to prevent bad practice (i.e if(x) on a non boolean type) - but so that I can correctly modify - would the if(floatValue) only return false if floatValue was zero ? – Ronald Palmer Oct 02 '15 at 20:32
  • What for existing code ? There can be thousands of conditions like that. – iEngineer Dec 28 '15 at 10:08

3 Answers3

6

It depends how the cast from a CGFloat to a Bool is implemented. This could depend on Objective-C's implementation or even on the actual processor's implementation of the IEEE floating point spec.

Either way, you should definitely not be relying on that. Especially since floats are not guaranteed to be accurate. You could end up with something incredibly close to 0, but have the if statement fail.

You should explicitly test the float against the value you are looking for like so:

if (floatValue != 0.0f)
{
    //we know exactly what will happen
}

In Swift, the compiler wouldn't even let you do something like this because it tries to keep you safe:

if (floatValue)
{
    //might happen, might not. who knows
}

In Swift, you may only use if (variable) syntax if variable is of type Bool.

The Objective-C compiler won't force you into this behavior, but you should abide by it if you want your code to run predictably and be portable.

tanner0101
  • 4,005
  • 19
  • 33
  • `if (floatValue == 0.0f)` <-- this is likely to fail. Don't use `==` comparison on float\double values. – FreeNickname Oct 02 '15 at 21:18
  • 2
    The binary representation of a float at exactly 0 is 0. This test will pass for that case. If you are trying to check for a value close to 0, then you should use > and – tanner0101 Oct 02 '15 at 21:22
  • 2
    Either way, relying on the mantissa being truncated is not a good idea. – tanner0101 Oct 02 '15 at 21:31
  • 2
    Sorry, it turns out, my vision of Objective-C interpretation of `float`s in `if` conditions was wrong. I will remove the downvote in ~30 minutes (it is locked now). I thought it is converted to int (BOOL is represented as int underneath, AFAIK). But I ran some experiments, and it seems that it treats anything not equal to `0.0` like `YES`. I thought, `1e-30` should produce `NO`. But it's a `YES`. Clearly I'm not competent enough to vote in this question :) – FreeNickname Oct 02 '15 at 21:44
  • 1
    FYI - `if (floatValue)` would need to be `if (floatValue != 0.0f)`, not `if (floatValue == 0.0f)`. – rmaddy Oct 02 '15 at 21:46
  • @rmaddy just fixed it. – tanner0101 Oct 02 '15 at 21:48
2

You need to ask explicitly whether floatValue is equal to 0.0, or, even better, whether its absolute value is less than some acceptable epsilon (such as 0.000001).

Either that, or just truncate by coercing to NSInteger explicitly — but that would be rather silly, as 0.9 would end up as 0.

matt
  • 515,959
  • 87
  • 875
  • 1,141
0

Implicit conversion turns floating-point number into integer: 'CGFloat' to 'bool'

It's important also to mention that CGFloat here is being converted (at least tries to be) to bool rather than BOOL. That's basically because the thing is happenning on ARM64 (see https://www.bignerdranch.com/blog/bools-sharp-corners/). As the folks above say it's necessary to explicitly compare against "the absolute value of zero". However, that doesn't always mean comparing to 0.0f or 0.0 (see this post: https://stackoverflow.com/a/10334944/2799410). BTW, matt has just pointed out that comparing to zero with a treshold is a better idea than just comparing to 0.0 and/or 0.0f.

Community
  • 1
  • 1
Arthur Gevorkyan
  • 2,069
  • 1
  • 18
  • 31