NSString to 64-bit integer conversion on iPhone - iphone

I am struggling with very simple thing:
I receive some ids by http request as a string. I know they represent 64-bit integer id numbers.
How can I convert them to the 64-bit Integers (NSNumber or NSInteger)?
Functions like:
[nsstring integerValue],
[nsstring intValue]
seems to be 32bit limited (max value:2147483647).
Any Hints?
Data model with 64bit integer properties compiles fine so it means iPhone supports such a numbers for a god sake.
It must be some simple conversion method. It is so popular in http connection based devices.

have you tried longLongValue ?

if they have a fixed length, you could cut them on each 9th number, make the intvalue of the cutted parts and add the values with the 10^9-factor. surely not the most elegant way, but it should work

Related

JSONKit changing float values on decoding JSON object from webservice in iphone

Float values are getting changed after parsing with JSONKit. The problem occurs after calling objectFromJSONString or mutableObjectFromJSONString.
The JSON response is fine before this method is triggered in JSONKit.m:
static id _NSStringObjectFromJSONString(NSString *jsonString, JKParseOptionFlags parseOptionFlags, NSError **error, BOOL mutableCollection)
Original response:
"value":"1002.65"
Response after calling objectFromJSONString:
"value":"1002.6500000001" or sometimes "value":"1002.649999999 "
Thanks.
This is not an issue.
The value 1002.65 can not be represented exactly using a IEEE 754 floating point number.
Floating-point numbers are converted to their decimal representation using the printf format conversion specifier %.17g. 
From the Docs:
The C double primitive type, or IEEE 754 Double 64-bit floating-point,
is used to represent floating-point JSON Number values. JSON that
contains floating-point Number values that can not be represented as a
double (i.e., due to over or underflow) will fail to parse and
optionally return a NSError object. The function strtod() is used to
perform the conversion. Note that the JSON standard does not allow for
infinities or NaN (Not a Number). The conversion and manipulation of
floating-point values is non-trivial. Unfortunately, RFC 4627 is
silent on how such details should be handled. You should not depend on
or expect that when a floating-point value is round tripped that it
will have the same textual representation or even compare equal. This
is true even when JSONKit is used as both the parser and creator of
the JSON, let alone when transferring JSON between different systems
and implementations.
Source: See this thread https://github.com/johnezang/JSONKit/issues/110
Solution: You can specify a precision, while converting float to string for output. NSNumberFormatter will be a better choice or use some printf solutions like in the previous answer.
use float fixed point representation like,
NSLog(#"value = %.2f",floatvalue);
now it will show value = 1002.65

Adding large Power values in Xcode

I am new to Objective C and iPhone development.
I'm working with a basic calculator. I want to add a large value in text field. How can I display large values like this : 6.67543 x 10^ -34 in Xcode?
Thank you
You could set up a NSNumberFormatter with NSNumberFormatterScientificStyle and call stringFromNumber... However, the issue I think is going to be with the precision you are hoping to support requires a specialized framework. There might be one based on GNU MP Bignum library out there, but I don't know it off hand.
Use Double data type. And then convert it into string then pass that string to your textField.
For eg:-
double result;
NSString *strResult = [[NSNumber numberWithDouble:result] stringValue];
It will give you exponential string.
And instead of a UILabel use UITextField.

iPhone int parsing

I'm working on an iPhone app. I want to parse a series of numbers from a string. However, intValue is acting really really strange.
I have a string with the value 1304287200000.
I then place the intValue of that into an NSInteger, and lo and behold, my integer is for some reason assigned the value of 2147483647.
What gives?
The datatype int is a 32bit numeric value, with a range of approximately ±2 billion. 1304287200000 is by a margin outside of that range.
You need to skip int for long long that is a 64bit type and covers your need. A more human readable and explicit name for the 64bit type is int64_t.
What you are getting back is INT32_MAX, because the parsed value overflows the int type. This is explained in the NSString documentation. Try longLongValue instead, LLONG_MAX should be big enough.
int is 32-bit, so the maximum value it can hold is 2,147,483,647. Try longLongValue instead.
Your number exceeding integer limits

How should I declare a long in Objective-C? Is NSInteger appropriate?

I see NSInteger is used quite often and the typedef for it on the iPhone is a long, so technically I could use it when I am expect int(64) values. But should I be more explicit and use something like int64_t or long directly? What would be the downside of just using long?
IIRC, long on the iPhone/ARM is 32 bits. If you want a guaranteed 64-bit integer, you should (indeed) use int64_t.
Integer Data Types Sizes
short - ILP32: 2 bytes; LP64: 2 bytes
int - ILP32: 4 bytes; LP64: 4 bytes
long - ILP32: 4 bytes; LP64: 8 bytes
long long - ILP32: 8 bytes; LP64: 8 bytes
It may be useful to know that:
The compiler defines the __LP64__ macro when compiling for the 64-bit runtime.
NSInteger is a typedef of long so it will be 32-bits in a 32-bit environment and 64-bits in a 64-bit environment.
When converting to 64-bit you can simply replace all your ints and longs to NSInteger and you should be good to go.
Important: pay attention to the alignment of data, LP64 uses natural alignment for all Integer data types but ILP32 uses 4 bytes for all Integer data types with size equal to or greater than 4 bytes.
You can read more about 32 to 64 bit conversion in the Official 64-Bit Transition Guide for Cocoa Touch.
Answering you questions:
How should I declare a long in Objective-C? Is NSInteger appropriate?
You can use either long or NSInteger but NSInteger is more idiomatic IMHO.
But should I be more explicit and use something like int64_t or long directly?
If you expect consistent 64-bit sizes neither long nor NSInteger will do, you'll have to use int64_t (as Wevah said).
What would be the downside of just using long?
It's not idiomatic and you may have problems if Apple rolls out a new architecture again.
If you need a type of known specific size, use the type that has that known specific size: int64_t.
If you need a generic integer type and the size is not important, go ahead and use int or NSInteger.
NSInteger's length depends on whether you are compiling for 32 bit or 64 bit. It's defined as long for 64 bit and iPhone and int for 32 bit.
So on iPhone the length of NSInteger is the same as the length of a long, which is compiler dependent. Most compilers make long the same length as the native word. i.e. 32 bit for 32 bit architectures and 64 bit for 64 bit architectures.
Given the uncertainty over the width of NSInteger, I use it only for types of variables to be used in the Cocoa API when NSInteger is specified. If I need a fixed width type, I go for the ones defined in stdint.h. If I don't care about the width I use the C built in types
If you want to declare something as long, declare it as long. Be aware that long can be 32 or 64 bit, depending on the compiler.
If you want to declare something to be as efficient as possible, and big enough to count items, use NSInteger or NSUInteger. Note that both can be 32 or 64 bits, and can be actually different types (int or long), depending on the compiler. Which protects you from mixing up types in some cases.
If you want 32 or 64 bit, and nothing else, use int32_t, uint32_t, int64_t, uint64_t. Be aware that either type can be unnecessarily inefficient on some compiler.

How do you use the different Number Types in Objective C

So I am trying to do a few things with numbers in Objective C and realize there is a plethora of options, and i am just bewildered as to which type to use for my app.
so here are the types.
NSNumber (which is a class)
NSDecmial (which is a struct)
NSDecimalNumber (which is a class)
float/double (which are primitive types)
so essentially what i need to do is take an NSString, which is representing decimal based hours. (10.4 would be 10 hours and (4/10)*60 minutes) and convert it into:
a string representation D H:M (this needs division, multiplication and basic arithmatic)
a Number type to store for easy calculations latter (will mostly be converting between NSTimeIntervals and doing subtractions)
Oh and i need to be able to do an Absolute value as well on these
It appears that the hard part is actually transitioning between the types.
To me this is a very trivial problem so I"m not sure if its getting late or because objective C numerical types suck, but i could use a hand.
Use primitive types (double, CGFLoat, NSInteger) for typical arithmetic and when you need to store a number as an instance variable that's going to be used primarily for arithmetic in other places. You can use C math functions (abs(), pow(), etc) as needed. NSTimeInterval is a typedef for double, so you can interchange the two.
Use NSNumber when you need to store a number as an object, for example if you're creating an NSArray of numbers. Some parts of Cocoa like Core Data or key value coding deal more with NSNumber than primitive types, so you may find yourself using NSNumber more then usual in those situations. For example, if you write [timeKeepersArray valueForKeyPath:#"sum.seconds"] you'll get back an NSNumber, so you may find it easier just to keep that variable instead of converting it to a primitive.
Since it's a small amount of extra code to convert between NSNumber and primitive types, usually your application will end up favoring one or the other depending on what you're doing with numbers.
Oh, and NSDecmial and NSDecimalNumber? Don't worry too much about them, they only come up when you need really precise decimal operations, such as if you're storing financial data.