Objective c min max operation - objective-c

Can you explain me why this code:
NSInteger i = -1;
NSUInteger x = 1;
NSLog(#"min = %lu", MIN(i, x));
NSLog(#"max = %lu", MAX(i, x));;
prints
min = 1
max = 18446744073709551615

You compare two different types: signed (NSInteger) and unsigned (NSUInteger). MIN/MAX convert all to unsigned integer.
Moreover, negative NSInteger is printed with %lu instead of %du. Therefore see a big number.
NSInteger i = -1;
NSUInteger x = 1;
NSLog(#"min = %ld", MIN(i, (NSInteger)x));
NSLog(#"max = %ld", MAX(i, (NSInteger)x));

It's because i is actually being converted into an unsigned int implicitly. See here. As a result it rolls over to 18446744073709551615.

It is because i is being implicitly converted to an unsigned long. It is part of the way xcode handles integer conversions. Here is a similar post. NSUInteger vs NSInteger, int vs unsigned, and similar cases

Related

Objective C: NSRange location value is not what it should be

I have this method which extracts data from NSData at a specific pointer. The method only extracts a certain amount of bytes, in this case it is 4 bytes as I return a uint32.
I pass in a pointer (int start) which is used to create the location for an NSRange, the length of the range is the size of a uint32, which creates the range as 4 bytes long.
This works perfectly fine, until the pointer gets to 2147483648. When it gets to this value, the range is not created with 2147483648 for the location value instead it is created as 18446744071562067968 which is out of bounds for the data, and causes an exception to occur halting my program which stops it from reading the rest of the data.
I have no idea what is causing it do what its doing, the start value is the correct value when it is passed into the method, but it changes when the range is created. It does not happen for any of the previous pointer values.
Have I done something silly in my code? Or is it a different problem? Help will be appreciated.
Thank you.
- (uint32)getUINT32ValueFromData:(NSData *)rawData pointer:(int)start {
uint32 value;
NSRange range;
int length = sizeof(uint32);
NSUInteger dataLength = rawData.length;
NSData *currentData;
NSUInteger remainingBytes = dataLength - start;
if (remainingBytes > length) {
range.location = start;
range.length = length;
//should be 2147483648, location in range is showing 18446744071562067968 which is out of bounds...
currentData = [rawData subdataWithRange:range];
uint32 hostData = CFSwapInt32BigToHost(*(const uint32 *)[currentData bytes]);
value = hostData;
pointer = start + length;
}
else
{
NSLog(#"Data Length Exceeded!");
}
return value;
}
It's seems to be an 32/64 bit and signed/unsigned mismatch issue.
You're using three different types
int is a 32 bit signed type
uint32 is a 32 bit unsigned type
NSUInteger is a 32/64 bit unsigned type depending on the processor architecture.
unit32 for the value is fine, but you should use NSUInteger for the offset into the NSData object.

NSString to int loses precision

I have a text string that represents a certain value without floating point number:
NSString *value1 = #"20141014135017";
NSString *value2 = #"20141014131024";
int one = [value1 intValue];
int two = [value2 intValue];
Why the result of one and two is only 2147483647? How can I solve this problem?
It depends on the platform, but on a 32-bit platform the limit of int is +/- 2 billion (−2,147,483,648 to 2,147,483,647 to be precise).
Use long instead:
long one = [value1 longValue];
long two = [value2 longValue];
int values can only support a limited number of bits. You should use float or double.
Here is a more comprehensive text on integers link

Converting decimal number to binary Objective-C

Hi I have made an IOS app that converts binary, hexadecimal and decimal values. It all works fine except for my decimal to binary conversion. Here is what I have. It returns 0s and 1s but far too many. Can anyone tell me why this is or help me with a better method?
NSString *newDec = [display text]; //takes user input from display
NSString *string = #"";
NSUInteger x = newDec;
int i = 0;
while (x > 0) {
string = [[NSString stringWithFormat:#"%u", x&1] stringByAppendingString:string];
x = x>> 1;
++i;
}
display.text = string; //Displays result in ios text box
Try this:
NSUInteger x = [newDec integerValue];
And next time don't ignore the Compiler's "Incompatible pointer to Integer conversion" hint...
Explanation: Afaik, assigning an object to an int, actually assigns the address of the object to that integer, not the content of the string (which is what you want).

Binary conversion algorithm in objective-c

How do I get the value of a certain bit from a byte or integer? The only similar answer that I've been able to find is for a specific character inside a string. I am trying to convert a binary number to a decimal number, and perhaps there is a much simpler way to do this, but I was thinking of this: multiplying 2^(position of integer from right) by either a 1 or 0, depending on the value of the integer at the position previously mentioned. Any tips?
NSString * binary = #"0011010";
long value = strtol([b UTF8String], NULL, 2);
There are multiways of obtaining the value of bit within a byte or integer. It all depends on your needs.
One way would be to use a mask with bitwise operators.
int result = sourceValue & 8; // 8 -> 0x00001000
// result non zero if the 4th bit from the right is ON.
You can also shift bits one by one and read, say, the right-most bit.
for (int i = 0; i < 8; i++)
NSLog(#"Bit %d is %#", i, (sourceValue % 2 == 0) ? #"OFF" : #"ON");
sourceValue = sourceValue >> 1; // shift bits to the right for next loop.
}
Or if you just want the text representation for an integer, you could let NSNumber do the work:
NSString* myString = [[NSNumber numberWithInt:sourceValue] stringValue];

how to convert byte value into int in objective-c

Please tell me how to convert bytes to NSInteger/int in objective-c in iPhone programming?
What do you mean by "Bytes"?
If you want convert single byte representing integer value to int (or NSInteger) type, just use "=":
Byte b = 123;
NSInteger x;
x = b;
as Byte (the same as unsigned char - 1 byte unsigned integer) and NSInteger (the same as int - 4 bytes signed integer) are both of simple integer types and can be converted automatically. Your should read more about "c data types" and "conversion rules".
for example http://www.exforsys.com/tutorials/c-language/c-programming-language-data-types.html
If you want to convert several bytes storing some value to int, then convertion depends on structure of these data: how many bytes per value, signed or unsigned.
If by byte, you mean an unsigned 8 bit value, the following will do.
uint8_t foo = 3; // or unsigned char foo...
NSInteger bar = (NSInteger) foo;
or even
NSInteger bar = foo;
My guess:
unsigned char data[] = { 0x00, 0x02, 0x45, 0x28 };
NSInteger intData = *((NSInteger *)data);
NSLog(#"data:%d", intData); // data:675611136
NSLog(#"data:%08x", intData); // data:28450200
So, beware of byte-order.
NSInteger x = 3;
unsigned char y = x;
int z = x + y;
Use the "=" operator.