Can´t get the unsigned long value of a NSNumber - iphone

I want to get the unsigned long value of a NSNumber. I don´t know why, but it doesn't work. Here is what I did:
NSString * stern = [idd objectAtIndex:indexPath.row]; // get a String with Number from a NSArray
NSNumberFormatter * lols = [[NSNumberFormatter alloc] init];
NSNumber * iddd = [lols numberFromString:stern];
NSLog(#"%#", iddd); // I get the right number: 8084143463
unsigned long fooo = [iddd unsignedLongValue];
NSLog(#"%lu", fooo); // I get the wrong number: 3789176167
[twitterEngine deleteUpdate:fooo];

8084143463 == 0x1e1da3d67
3789176167 == 0x0e1da3d67
The size of a long on a 64bit system is 8 bytes. The size of a long on a 32bit system (like the iPhone) is 4 bytes. You need to use a long long on an iPhone to store that value.

Your value is larger than the maximum value an unsigned long can hold (2^32 - 1 == 4,294,967,295) in 32-bit mode.

Related

Convert NSNumber to hex string with 16 digits

I have to convert an NSNumber to a hex string like follows:
return [NSString stringWithFormat:#"%llX", self.unsignedLongLongValue];
Unfortunately, this will sometimes give me string like 93728A166D1A287 where they should be 093728A166D1A287, depending on the number.
Hint: the leading 0.
I've also tried it with:
return [NSString stringWithFormat:#"%16.llX", self.unsignedLongLongValue];
without success.
I could do something like this, but that just sucks:
- (NSString *)hexValue {
NSString *hex = [NSString stringWithFormat:#"%llX", self.unsignedLongLongValue];
NSUInteger digitsLeft = 16 - hex.length;
if (digitsLeft > 0) {
NSMutableString *zeros = [[NSMutableString alloc] init];
for (int i = 0; i < digitsLeft; i++) [zeros appendString:#"0"];
hex = [zeros stringByAppendingString:hex];
}
return hex;
}
So finally my question, is there a way to enforce the string to be 16 characters?
If you need to zero-pad your hex numbers, use zero in front of the format specifier, like this:
return [NSString stringWithFormat:#"%016llX", self.unsignedLongLongValue];
This should take care of formatting your number with 16 digits, regardless of how many "meaningful" digits the number has.
Here is a demo of this format string in plain C (this part is shared between the two languages).
Use:
return [NSString stringWithFormat:#"%016llX", self.unsignedLongLongValue];
Which sets leading 0 and the length of the output string.

NSInteger and facebookId

I made a request to facebook API using facebook SDK to get user basic data. Everything works ok, but when I try to pass the facebook ID as a NSInteger number the returned number is wrong.
The facebook ID is: 100001778401161
But after convert the number to NSInteger the number returned is: 2054848393
How can I store the facebook ID on a NSInteger variable?
My current code is:
NSLog(#"The ID: %ld", (long)[[user objectForKey:#"id"] intValue])
Thanks.
Such a number needs 64 bits, NSInteger does only cover 32 bits (and with positive numbers only 31 bits). Try using long long values:
NSLog(#"The ID: %lld", [[user objectForKey:#"id"] longLongValue]);
you can use also NSNumber if you need to store it as an object somehow:
NSNumber *number=[NSNumber numberWithLongLong:[user[#"id"] longLongValue]];
NSInteger (and long) is a 32-bit value and the ID you are using exceeds the maximum value that it can hold, so it overflows. You could try:
long long facebookId = [[user objectForKey: #"id"] longLongValue];
NSLog(#"The ID: %lld", facebookId);
I don't know anything about the facebook API so you might want to make sure that the ID is guaranteed to be numeric over time. If, for example, they specify somewhere that the ID is a string, you should match that even if they seem to always be numeric.
You can't store the number larger than 2 ^ 31 in NSInteger type.
If you want to store the one larger, then you can use NSDecimalNumber object instead.
Or you can use unsigned long long type.
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:[user objectForKey:#"id"]];
NSLog(#"Number: %#", number);
unsigned long long ullValue = strtoull([user objectForKey:#"id"], NULL, 0);
NSLog(#"Number: %llu", ullValue);
Hope this will help you!

Trying to save long long into NSNumber from String

I am trying to save a long long number (received as a string) such as '80182916772147201' into an NSNumber.
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterBehaviorDefault];
[item setObject:[f numberFromString:#"80182916772147201"] forKey:#"theID"];
[f release];
When I NSLog this out, assuming the string was '80182916772147201' I get:
NSLog(#"%lld", [[item objectForKey:#"theID"] longLongValue]);
Returns: '80182916772147200' - Note the rounded down final digit.
What am I doing wrong?
The problem is that NSNumberFormatter has decided to represent that number as a floating-point number. To force it to use integers only:
[f setAllowsFloats:NO];
Can you try this?
NSString *numStr = [NSString stringWithFormat:#"%llu", [myNum unsignedLongLongValue]];
This makes a few reasonable assumptions such as numStr will only contain numeric digits and it contains a 'valid' unsigned long long value. A drawback to this approach is that UTF8String creates what essentially amounts to [[numStr dataUsingEncoding:NSUTF8StringEncoding] bytes], or in other words something along the lines of 32 bytes of autoreleased memory per call. For the vast majority of uses, this is no problem what-so-ever.
For an example of how to add something like unsignedLongLongValue to NSString that is both very fast and uses no autoreleased memory as a side effect, take a look at the end of my (long) answer to this SO question. Specifically the example implementation of rklIntValue, which would require only trivial modifications to implement unsignedLongLongValue.

iPhone SDK : NSString NSNumber IEEE-754

Can someone help me ? I have a NSString with #"12.34" and I want to convert it into a NSString with the same float number but in single precision 32bits binary floating-point format IEEE-754 : like #"\x41\x45\x70\xa4" (with hexa characters) or #"AEp¤"...
I'm sure it's something easy but after many hours of reading the doc without finding a solution...
Thank you !
As Yuji mentioned, it's not a good idea to encode an arbitrary byte sequence into an NSString(although it can contain null bytes), as encoding transformations can(and probably WILL) destroy your byte sequence. If you want access to the raw bytes of a float, you may want to consider storing them as an NSData object(though I suggest you think through your reasons for wanting this first). To do this:
NSString *string = #"10.23";
float myFloat = [string floatValue];
NSData *myData = [[NSData alloc] initWithBytes:&myFloat length:sizeof(myFloat)];
If you want to get the raw bytes of a float, you could cast it, like so:
NSString *str = #"12.34";
float flt = [str floatValue];
unsigned char *bytes = (unsigned char *)&flt;
printf("Bytes: %x %x %x %x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
However the order in which these bytes are stored in the array depends on the machine. (See http://en.wikipedia.org/wiki/Endianness). For example, on my Intel iMac it prints: "Bytes: a4 70 45 41".
To make a new NSString from an array of bytes you can use initWithBytes:length:encoding:

How to display currency without rounding as string in Xcode?

I have trouble when I have currency value
999999999999999999.99
From that value, I want to display it as String. The problem is that value always rounded to
1000000000000000000.00
I'm not expect that value rounded. I want the original value displayed. Do you have any idea how to solve this problem? I tried this code from some answer/turorial in stackoverflow.com :
NSMutableString *aString = [NSMutableString stringWithCapacity:30];
NSNumberFormatter *aCurrency = [[NSNumberFormatter alloc]init];
[aCurrency setFormatterBehavior:NSNumberFormatterBehavior10_4];
[aCurrency setNumberStyle:NSNumberFormatterCurrencyStyle];
[aCurrency setMinimumFractionDigits:2];
[aCurrency setMaximumFractionDigits:2];
[aString appendString:[aCurrency stringFromNumber:productPrice]];
//productPrice is NSDecimalNumber which is have value 999999999999999999.99
cell.textLabel.text = aString;
NSLog(#"the price = %#",cell.textLabel.text);
//it prints $1,000,000,000,000,000,000.00
[aCurrency release];
Unless you have very good reasons not to, it is generally best to keep currency values in a fixed-point format, rather than floating point. Ada supports this directly, but for C-ish languages what you do is keep the value in units of pennies, rather than dollars, and only do the conversion whenever you go to display it.
So in this case the value of productPrice would be 99999999999999999999 (cents). To display it, you'd do something like this (If this were C. I don't know the language):
int const modulus = productPrice % 100;
printf ("The price = %d.%d\n", (int) ((productPrice - modulus) / 100), modulus);
I'd also use an integer rather than a floating point variable to keep the value in almost all cases. It won't work in this case (even if you use a 64-bit integer) because your value is mind-bogglingly large. We're talking 1 million times larger than the US National Debt! If a dollar value that large ever makes sense for anything in my lifetime, we are all in big trouble.
Have you tried these:
* – setRoundingBehavior:
* – roundingBehavior
* – setRoundingIncrement:
* – roundingIncrement
* – setRoundingMode:
* – roundingMode