I've below numbers which are stored as NSCFString into SQLite
These numbers converts perfectly
475602307163925662
1529228456639250520
I am converting these like, (NSNumber *) [myDictionary valueForKey:#"stringData"]; and its working perfectly
These numbers couldn't converts perfectly
14154269406789154303
13207084142614401684
12870871772958895646
I want to convert these NSCFString into NSNumber. I try using below code and google it but dont get exact solution as I want. Any help would be appriciated.
NSNumberFormatter *f=[[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *myNumber=[f numberFromString:[myDictionary valueForKey:#"stringData"]];
[f release];
but it converts my number something like 9.45214212452152
I tried some other way as well but its also not working well.
NSNumber *myNumber=[NSNumber numberWithLong:[myDictionary valueForKey:#"stringData"]];
Casting an object as another object (aka (NSNumber *)) does not "convert" it. It just promises the compiler that you're working with an object of that class which you aren't.
The reason why some numbers are totally failing is because they're too large to fit in the standard int/float/long sizes. Instead of NSNumber, use NSDecimalNumber - a subclass of NSNumber (so you can still use all of the NSNumber methods as well). It's specifically designed to handle large numbers:
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:<your string object>];
Related
I have built one 'deep' NSMutableDictionary that contains parsed XML data along with other relevant information that I can pass from one view controller to another. The NSMutableDictionary contains mostly NSStrings but also another NSMutableDictionary more NSStrings and finally followed even deeper with an NSMutableArray of custom objects (it's for a calendar).
Now, because it is a calendar, there are obviously dates involved. The XML data that I receive and parse using NSXMLParser returns strings, so it was on me to convert the day's date to usable numbers. The date in XML comes in with the following format: "MM.DD" I created the following method to do so:
- (void)createDateCodesWithString:(NSString *)string
{
NSInteger monthCode;
NSInteger dayCode;
....
NSArray *dates = [string componentsSeparatedByString:#"."];
monthCode = [[dates objectAtIndex:0] integerValue];
dayCode = [[dates objectAtIndex:1] integerValue];
....
shortDay = [NSNumber numberWithInt:dayCode];
}
'shortDay' is a NSNumber* and an ivar and set as a property (nonatomic, retain) for the custom object that I have created. When I run NSLog commands in the console, it appears that 'shortDay' and other data has been stored successfully in the deep NSMutableDictionary. I run in to problems, however, when I try to access the data again. When I access a NSString* stored ivar, things work OK, but when I attempt to access the NSNumber* I am given the error EXC_BAD_ACCESS with either code 1 or code 2. This is how I try to call upon the NSNumber*
NSNumber *number = day.shortDay;
return [number stringValue];
Might the problem be because the NSArray *dates strips the string into month and day strings and the day string, being two characters long, may contain a '0' before, say, a '6' if the day is the 6th of the month? Any advice?
I am happy to post more code if needed.
It's possible that the memory for shortDay is being cleaned up before the next time you try to access it. When assigning it, try this instead:
shortDay = [[NSNumber numberWithInt:dayCode] retain];
to increase the reference count (AKA take ownership of the object) to avoid the memory being deallocated too early.
If this resolves the problem, you will then need to call [shortDay release] in the dealloc method of your class, such that the memory for it will be properly deallocated at the right time.
I came across this fragment of Objective-C:
NSNumber *theBalance =
[[[NSNumberFormatter alloc] init]
numberFromString: [textField text]];
This seems to leak the NSNumberFormatter. In C++ I would do one of two things:
use auto (i.e. stack) storage for the NSNumberFormatter
use RAII (e.g. shared_ptr) to manage the life of the NSNumberFormatter
In Objective-C neither of these options seem to be possible. I tried on the stack:
NSNumberFormatter fmt;
But this doesn't compile. As far as I can find there's no direct equivalent of RAII in Objective-C. I'm probably looking at the problem from the wrong angle as a mainly C++ programmer, so:
In the general case what's the correct, idiomatic (modern) Objective-C way of handling the life of objects like the NSNumberFormatter here? Do I really have to do it explicitly myself?
In the specific case is there a better way of solving the actual problem?
Most of the classes like NSString, NSArray, and so on, have the convenience constructors like, [NSString string] and [NSArray array] which return the autoreleased objects. NSNumberFormatter doesn't have any convenience constructors. So, you can send a autorelease message to let it autoreleased when the autorelease pool drains.
NSNumber *theBalance = [[[[NSNumberFormatter alloc] init] autorelease]
numberFromString: [textField text]];
If you want to retain(own) the reference of the object, you can omit the autorelease and release it later when you are done with it. You do it like this,
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSNumber *theBalance = [numberFormatter numberFromString: [textField text]];
// Later... somewhere in your code...
[numberFormatter release];
I know the above is not a detailed explanation. I'd suggest you to read this post by which, I hope, you would get some clear idea about memory management!
I have an interface giving me numbers like this 0000000012345,78
So i figured out how to make a number out of them. But I need to calculate with that number and what I actually need is a decimal number.
NSNumberFormatter *fmtn = [[NSNumberFormatter alloc] init];
[fmtn setFormatterBehavior:NSNumberFormatterBehavior10_4];
[fmtn setNumberStyle:NSNumberFormatterDecimalStyle];
[fmtn setDecimalSeparator:#","];
NSNumber *test = [fmtn numberFromString:#"0000000012345,78"];
How can I make my NSNumber to a NSDecimalNumber?
EDIT: This is the code I ended up with:
NSDictionary *localeDict = [NSDictionary dictionaryWithObject:#"," forKey:#"NSDecimalSeparator"];
NSDecimalNumber *test = [[NSDecimalNumber alloc] initWithString:#"00000000012345,78" locale:localeDict];
How to put together the locale dictionary could not be described as "well documented" and it took me some googling to find an example.
This one also worked:
NSLocale *deLoc = [[NSLocale alloc] initWithLocaleIdentifier:#"de"];
NSDecimalNumber *testd = [NSDecimalNumber decimalNumberWithString:#"00000000012345,78" locale:deLoc];
To convert an NSNumber to NSDecimalNumber, wouldn't it make more sense to avoid the character representation altogether with this code?
NSNumber* source = ...;
NSDecimalNumber* result = [NSDecimalNumber decimalNumberWithDecimal:[source decimalValue]];
If you check out the NSDecimal Class Reference, you'll see you can create new NSDecimalNumbers from NSStrings (with and without a locale), actual numbers, etc.
If you wanted to convert an NSNumber to an NSDecimalNumber, you could do something like this:
NSDictionary *locale = ...;
NSNumber *number = ...;
NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithString:[number descriptionWithLocale:locale] locale:locale];
Of course, you'll have to correctly create the locale, and such, but that's an exercise left up to you (it might be handy to check out the NSNumber Class Reference, the NSLocale Class Reference, and the Locales Programming Guide).
[NSDecimalNumber decimalNumberWithString:#"0000000012345,78"];
Use caution about the locale, though; if you run that code on an iPhone whose region format is not set to French, it might not return what you expect. So you might want to use:
+ (NSDecimalNumber *)decimalNumberWithString:(NSString *)numericString locale:(NSDictionary *)locale
instead.
I hope I don´t annoy you and you don´t have to answer this, but
here is a little bit more explanation of my problem. I got all of the ids of the tweets with a NSArray. Then I set a NSNumber with:
NSNumber =[NSArray objectAtIndex:indexPath.row];
to get the right id of the tweet in the TableView row. Now I just wrote this:
unsigned long fooo = NSNumber;
NSLog("%#", fooo) // The right number
[twitterEngine deleteUpdate:fooo];
But the finalURL has a other number. So for example fooo is: 8043688359, the finalUrl is this:
finalURL = https://twitter.com/statuses/destroy/62024352.xml
Also I get the HTTP error 403
All other methods like sendUpdate, getTimeline etc. are working.
Just the deleteUpdate and the sendUpdate: inReplyTo aren´t
working. I think it has something with a wrong number to do.
Sorry for my bad English, bad I´m a young student from Germany
and I´m just learning Objective-C (or programming generally) for
three weeks.
The original methodes looking like that:
- (NSString *)sendUpdate:(NSString *)status inReplyTo:(unsigned long)updateID; // statuses/update
- (NSString *)deleteUpdate:(unsigned long)updateID; // statuses/destroy
Thanks!
Got the answer: The MGTwitterEngine wants a unsigned long, but the iPhone is 32bit and so the the 64bit number gets smaller and MGTwitterEngine gets the wrong number.
You have to edit the MGTwitterEngine. Just write unsigned long long in the methods.
NSNumber is a class not an instance. The code could look something like the following:
NSNumber *myNumber = [NSArray objectAtIndex:indexPath.row];
unsigned long fooo = [NSNumber longValue];
NSLog("%l", fooo); // The right number
[twitterEngine deleteUpdate:fooo];
The return from -objectAtIndex: is an object and long is a primitive value. So you need to get the primitive long value out of the NSNumber object.
BTW, the odd number you are getting back is the memory address for the instance of the NSNumber.
Aproach it differently, as far as I can tell your code is something like:
NSNumber *aNumber = [anArray objectAtIndex:index.row];
unsigned long = aNumber;
In stead of using a unsigned long you should use a NSUinteger btw.
and doing it more directly:
NSUInteger anInteger = [[anArray objectAtIndex:index.row] longValue]; // or longLongValue];
done.
Tell me if I mis understood you.
I'm new to Objective-C and iPhone development, and I'm trying to store floating-point values in an NSMutableArray, but when I do I get an error saying "incompatible type for argument 1 of 'addObject". What am I doing wrong? I'm trying to create an array of doubles that I can perform math calculations with.
NSMutableArray only holds objects, so you want an array to be loaded with NSNumber objects.
Create each NSNumber to hold your double then add it to your array. Perhaps something like this.
NSMutableArray *array = [[NSMutableArray alloc] init];
NSNumber *num = [NSNumber numberWithFloat:10.0f];
[array addObject:num];
Repeat as needed.
Use an NSNumber to wrap your float, because the dictionary needs an object:
[myDictionary setObject:[NSNumber numberWithFloat:0.2f] forKey:#"theFloat"];
/* or */
[myDictionary setObject:#0.2f forKey:#"theFloat"];
retrieve it by sending floatValue:
float theFloat = [[myDictionary objectForKey:#"theFloat"] floatValue];
Code is untested.
You can wrap many other data types in NSNumber too, check the documentation. There's also NSValue for some structures like NSPoint and NSRect.
In Cocoa, the NSMutableDictionary (and all the collections, really) require objects as values, so you can't simply pass any other data type. As both sjmulder and Ryan suggested, you can wrap your scalar values in instances of NSNumber (for number) and NSValue for other objects.
If you're representing a decimal number, for something like a price, I would suggest also looking at and using NSDecimalNumber. You can then avoid floating point inaccuracy issues, and you can generally use and store the "value" as an NSDecimalNumber instead of representing it with a primitive in code.
For example:
// somewhere
NSDecimalNumber* price = [[NSDecimalNumber decimalNumberWithString:#"3.50"] retain];
NSMutableArray* prices= [[NSMutableArray array] retain];
// ...
[prices addObject:price];
NSMutableArray *muArray = [[NSMutableArray alloc] init];
NSNumber *float = [NSNumber numberWithFloat:210.0f];
NSNumber *float1 = [NSNumber numberWithFloat:211.0f];
[muArray addObject:float];
[muArray addObject:float1];
NSlog(#"my array is--%#",muArray);