Why / how could NSUInteger be returning a NEGATIVE number?
Asked Answered
C

2

6

What is the point of having a seperate unsigned type, aka NSUInteger if there is no guarantee (nor even, it seems, a chance) that you can assume, bet your bottom dollar on, or cry yourself to sleep for - what the name implies - an inherently nonnegative result.

NSUInteger normal = 5;
NSUInteger freaky = normal - 55;
NSLog(@"%ld, %ld", normal, freaky);

NSLOG 5, -50

Sure, I can bend over backwards trying to get zero, or some kind of normalized value…

NSUInteger nonNeg = (((normal - 55) >= 0) ? (normal - 55) : 0);

PARRALELUNIVERSELOG 5, -50

But here the compiler complains.. rightfully so that comparison of unsigned expression >= 0 is always true - and there it is, an answer I didn't want / expect. Someone slap my face, get me a drink, an tell me what year it is.. or better yet… how to make it - you know - not do that.

Chokebore answered 2/8, 2012 at 5:48 Comment(0)
E
9

%ld tells NSLog to print it as a signed integer. Try %lu.

See 2's Complement on wikipedia for an explanation of what's going on at the bit level.

What is happening here is that subtraction is causing the unsigned integer representation to wrap-around. To protect against this you need to check before you do the subtraction.

NSUInteger x = 5; 
NSUInteger y = 55;

// If 0 makes sense in your case
NSUInteger result = (x >= y) ? (x - y) : 0; 

// If it should be an error
if(x < y)
{
    // Report error
}
Eggplant answered 2/8, 2012 at 5:50 Comment(4)
I'm checking it out now.. but for example with %lu the results for nonNeg = 18446744073709551566. but hey, at least it's positive, right… lol.Chokebore
Well until you understand 2's Complement arithmetic it will always be puzzling to you ;-) So you had nonNeg = (5 - 55) and you get a confusing number... If you add 60 to this confusing number you will get 10 which is the correct answer!!! My point is there is a consistent system going on here... You just don't understand it yet. Do check out the wikipedia link. It will help. Honest!Eggplant
I tried to read that mind-bending article... again... and still have a fundamental question... Regardless of the dizzyingly-complex-implementation, why have a type that purports to be "sign-blind" if it can so-easily be "coerced" into unknown (negative) territory. Common sense says, "If it is UNsigned... it will never be less than 0", yet practically, this cannot be relied upon.Chokebore
Sorry for the delay in replying, been away from SO for a while. The unsigned type is never less than zero. However if you tell the compiler to interpret a piece of memory that holds a unsigned type as a signed type then that value may be less than zero. Hope this makes things clearer.Eggplant
K
0

The real answer is how the bits are being interpreted. Sure, it's important to understand how things are done internally, via 2's complement, but the confusion seems more to be that you're seeing a negative number when using %ld and think that it's somehow different than the positive number you see when using %lu. Both cases are using the same bits, it's simply a function of how they're being interpreted. You'd get different results if you tried to interpret those same bits as a sequence of characters.

Kirkman answered 4/9, 2015 at 19:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.