Reputation: 117
float test=-1;
produces a float
with value -1
. However,
float test=arc4random()%500-500;
produces enormous values that clearly resulted from a buffer overflow -- the numbers wrapping around. This should not happen with a float
; for kicks, I tried to see if Xcode would let me make a "signed float", but it told me "floats cannot be signed or unsigned."
I produced a work-around where I made a signed int
, then cast it to a float
, but I'd really appreciate knowing how/why this happened.
Upvotes: 3
Views: 166
Reputation: 124997
arc4random()
returns a u_int32_t
according to the man page, so arc4random()%500-500
will be an unsigned integer, and subtracting 500 will give you a very large positive value. Try this instead:
float test = ((float)(arc4random() % 500))-500;
I produced a work-around where I made a signed int, then cast it to a float, but I'd really appreciate knowing how/why this happened.
Look at the entire line one piece at a time. First, you've got:
arc4random()
As I said above, that returns an unsigned int. Let's pretend that it returns the value 12345
. Next, you've got the modulus operator, so your expression is something like:
12345 % 500
which is to say 345
. Next, you subtract 500:
345 - 500
You'd think that'd give you -155, but no -- we're still working in the realm of unsigned ints here, so you really get 4294967141
(or something like that -- my math may be off). Then, finally, you assign that to a float:
float test = 4294967141;
A float only has 23 bits for the mantissa, so the value that's stored in test
will be in the general neighborhood of 4294967141, but with less precision, like 4294970000.
Upvotes: 10
Reputation: 12770
floats in Objective-C are exactly the same as they are in C: inherently signed as defined by IEEE-754. http://en.wikipedia.org/wiki/Single_precision_floating-point_format
Upvotes: 0