NSNumber and float casting

In my application, I am using an external API that communicates with json. Today I ran into strange (this may be strange only due to my inexperience in iOS) behavior between floats and NSNumbers. The thing is, I get a float in the API response, in this particular case it's 135.99. When the native parjer obj-c json parses the response, it creates an NSNumber with this value. It works great. But when I started using this API, I didn't know how native json parser works, so I was doing something like this:

NSNumber * number = [NSNumber numberWithFloat:[[response objectForKey:@"Number"] floatValue]];

      

So what is happening above is actually casting the NSNumber to float and create a new NSNumber with that float. And what's so strange about that? The strange thing (for me) is that the above line generates an NSNumber with a value ... 135.99001 instead of 135.99 which is correct.

I know that float arithmetic is really messed up, especially in languages ​​like PHP (0.2 + 0.7 is not equal to 0.9), but I didn't expect that in languages ​​like objective-c, which is a superset od C language, I would find this a mess. Does anyone have a good explanation for this question?

+3


source to share


3 answers


You are making a beginner's mistake and "float" is assumed to be the correct floating point type. Not this. Unless you have a really compelling reason to use float, "double" is the type you should use. JSON parsers will inevitably use [NSNumber numberWithDouble: ...] to create the NSNumber objects they hold (or [NSNumber numberWithLongLong: ...] or NSDecimalNumber), but never [NSNumber numberWithFloat:].



float has very limited precision compared to double. You can be sure that in most cases [NSNumber numberWithFloat: ...] will give you different results due to limited precision.

+2


source


For languages ​​like C (and I suspect PHP too), float (and double) arithmetic is not language specific, but underlying hardware.



For modern computers, which means IEEE floating point arithmetic implemented by the processor, so you'll have the same problems if you wrote your program in C, Pascal, FORTRAN, etc. They are all simply called CPU floating point instructions and leave that at that.

0


source


Odd things happen with floats. They are part of their nature that they did not come true.

Also, I don't quite understand why you are converting (and not just typing) your nice NSNumber to float just to create a new NSNumber object from the float, you should never expect two float values ​​to be equal even if you cannot think of any reason why they should be different. This means that when it comes to comparing floats, you should never compare float1 == float2

. Better compare abs(float1-float2) < 0.001

or what value matters.

Some general information about these floats is well explained on this site: http://floating-point-gui.de/

-1


source







All Articles