It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I need to store a decimal number and neither a string, int or number seem to do what i want. I cannot use NSNumber because I need to be able to change it later.
I searched the whole internet but I doesn't seem to be able to find it.
The answer is probably pretty simple.
Thanks!
UPDATE:
some kind of data here
looping code{
nslog(save number);
save number 3.1415926535;
delete all data that has been stored
//now string doesn't exist anymore
}
I need to be able to save that number outside the loop in "some kind of data here" because when the loop starts over everything that is created from the loop is deleted.
Try using NSNumber like so:
double myValue = 20.0;
NSNumber* number = [NSNumber numberWithDouble:myValue];
// Do something with NSNumber like write it to disk, put it in an array, dictionary whatever ....
// Then pull it back out
double myOldValue = [number doubleValue];
To pull a double value out after the app has been closed (I'm interpreting that to mean "backgrounded" or "suspended"), try writing it to NSUserDefaults before the app is backgrounded and then pull it back out when your app resumes.
// Write a double to NSUserDefaults
[[NSUserDefaults standardUserDefaults] setDouble:myValue forKey:#"myDoubleValue"];
// Write an NSNumber to NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:number forKey:#"myNumberWithDoubleValue"];
// Extract double from NSUserDefaults
double myReallyOldDoubleValue = [[NSUserDefaults standardUserDefaults] doubleForKey:#"myDoubleValue"];
// Extract NSNumber from NSUserDefaults
NSNumber* myReallyOldNumberValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"myNumberWithDoubleValue"];
Or in your psuedo code:
NSNumber *someValue = [NSNumber numberWithDouble:0.0];
some kind of data here
looping code {
nslog(save number)
someValue = [NSNumber numberWithDouble:3.1412];
delete all data that has been stored
}
Store a pointer to your number or a instance variable or class property
You can use NSNumber, or is decimal subclass NSDecimalNumber. Just because the objects themselves are immutable doesn't mean you can't change the value a given variable points to. For example:
NSDecimalNumber *a = [NSDecimalNumber numberWithInt:2];
a = [a decimalNumberByAdding:[NSDecimalNumber numberWithInt:12]];
a = [a decimalNumberByDividing:[NSDecimalNumber numberWithDouble:2.3]];
This is just like real ints, which are also immutable.
double a = 2;
a = a + 12;
a = a / 2.3;
That being said, NSDecimalNumber is quite verbose. If you can get away with a primitive type (say, doing computations in cents instead of dollars) that might be preferable.
Just use a double. When it comes time to store it, you can get a number like this:
NSNumber *number = #(myDouble);
To change an NSNumber into a double,
double myDouble = [number doubleValue];
Related
I am trying to convert a NSNumber to long but I get this error:
[__NSSingleObjectArrayI intValue]: unrecognized selector sent to
instance
Here is my code:
NSNumber *dbversion = [settings valueForKey:#"Version"];
long dbver = [dbversion longValue];
What am I doing wrong here?
*settings is a NSArray and "Version" is the key for a long value.
You are caught in the Key-Value Coding trap.
In some cases the result of valueForKey is an array which the error message clearly states.
Don't Never use valueForKey(unless you know what KVC does and you need KVC), use key subscription.
And as settings is an array you might get the first item
NSNumber *dbversion = settings[0][#"Version"];
and int is not long
long dbver = [dbversion longValue];
However on a 64-bit machine I recommend to use NSInteger
NSInteger dbver = dbversion.integerValue;
//I think you are storing string from dictionary "settings" to NSNumber so it's showing error like you mention in question.
Please Try with solution. May this help you.
NSNumber *dbversion = [NSNumber numberWithLong:[[settings valueForKey:#"Version"] longLongValue]];
int dbver = [dbversion longValue];
This question already has answers here:
Objective C Issue With Rounding Float
(4 answers)
Closed 9 years ago.
The APP I'm writting must do some financial calculations, basically it's all about credits, debits and the balance. The only problem (so far) is that if I calculate 999999999.99 - 0.00 the result is 1000000000.00. Please, does anyone know why that happens? Here's my code:
NSNumber *totalCredits;
NSNumber *totalDebits;
NSNumber *balance;
self.credits = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
totalCredits = [self.credits valueForKeyPath:#"#sum.amount"];
double totalCreditsDouble = [totalCredits doubleValue];
self.creditLabel.text = [NSString stringWithFormat:#"%1.2f", totalCreditsDouble];
self.debits = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
totalDebits = [self.debits valueForKeyPath:#"#sum.amount"];
double totalDebitsDouble = [totalDebits doubleValue];
self.debitLabel.text = [NSString stringWithFormat:#"%1.2f", totalDebitsDouble];
balance = [NSNumber numberWithFloat:([totalCredits floatValue] - [totalDebits floatValue])];
double balanceDouble = [balance doubleValue];
self.balanceLabel.text = [NSString stringWithFormat:#"%1.2f", balanceDouble];
All the data is stored as Double.
The C type double is generally not very well suited for financial calculations.
Foundation.framework has a good data type for that: NSDecimalNumber. NSDecimalNumber uses a decimal representation and has 36 digits of precision.
http://floating-point-gui.de/ is a good resource to start with. You are trying to store exact values using a datatype which cannot represent them with the accuracy or precision you need.
if the integrity of these calculations is important to you then you need to switch to storing these values in a format which accurately represents them.
In this case a simple solution might be to store all of your currencies in their smallest possible denomination (e.g. cents) as integers (assuming you don't need fractional cents and handle any division carefully and consistently).
From my understanding of NSNumber, if you create NSNumber with a certain data type, you need to access the variable with that same data type. For example
NSNumber *myIntNumber = [NSNumber numberWithInt:1];
int myInt = [myIntNumber intValue];
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:1];
NSInteger myInteger = [myIntNumber integerValue];
If a NSNumber is created using a #define variable:
#define MY_DEFINE 6
does that mean that I cannot do the following
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:MY_DEFINE];
NSInteger myInteger = [myIntNumber integerValue];
because MY_DEFINE is not a NSInteger?
I know that the above code would work in a 32-bit app, but I am trying to make sure that it will work on a 64-bit app, which is much more picky about these things, as well. And of course, it never hurts to do things properly.
If I cannot do the above, should I try to define MY_DEFINE differently so that I could use it to create a NSNumber that can later be used to retrieve a NSInteger?
Your understanding of NSNumber is incorrect. You can create an NSNumber with any type it supports and you can then use any of the supported type accessors. The two do not need to the same.
// Perfectly valid
NSNumber *number = [NSNumber numberWithFloat:3.14];
int val = [number intValue]; // results in 3
Your use of the #define is perfectly valid. The pre-compiler simply translates your code to:
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:6];
Remember, a #define is nothing more than simple copy and paste (at least in this type of simple form) done before the code is compiled.
You can even use modern syntax:
NSNumber *number = #MY_DEFINE;
which becomes:
NSNumber *number = #6;
BTW - why post this question? Why not just try it first?
This question already has an answer here:
How to convert NSNumber objects for computational purposes?
(1 answer)
Closed 9 years ago.
I have an array:
SomeArray =[[NSMutableArray alloc]initWithObjects:[NSNumber numberWithFloat:50.0],[NSNumber numberWithFloat:120.0],[NSNumber numberWithFloat:200.0],nil];
When I retrieve it:
NSNumber* Target = [SomeArray objectAtIndex:0];
When I NSLog it:
NSLog(#"Target %d",Target);
it return something funky like
2013-06-26 01:47:58.940 KKK[1027:c07] Target 121016880
What is the proper way to do this?? I just need the number in the array to be used as float.
You are retrieving a NSNumber, which is an object.
%d is for logging decimals, which is not your case.
Either you log it with
NSLog(#"Target %#", target);
or you convert it to a float and use %f
NSLog(#"Target %f", [target floatValue]);
And PLEASE don't use capitalized identifiers for variables!
You are asking for a decimal %d in the log and also a primitive type. NSNumber is an object that wraps a primitive type numbers. So you can do like that
NSLog(#"target %f",[Target floatValue]) or NSLog(#"target %#",Target). With the first you are sending a message to the object to unwrap the float value with the latter you are asking for the object description that in this case is the number
My code looks like this
NSNumber *inputToNumber = [NSNumber numberWithFloat:[textField.text floatValue]];
the value from the textfield is actually a telephone number. It's stored in NSNumber as an annoying (2.0)78966e+08
How can I just get NSNumber to store it as 0207896608?
I think that the basic idea to store a phone number into a NSNumber is flawed:
how do you discriminate between numbers with or without leading 0 ?
how do you store phone numbers from foreign countries ?
I would use NSString in place of NSNumber.
Just because it's called a number doesn't mean a "telephone number" is a number in the same sense that "5" or "pi" are.
Either you should treat a telephone number as a string, or you should create a TelephoneNumber model class to represent each one.
Consider that there are places in the world where numbers don't have leading 0's and where a number with a leading 0 is not the same as the same number without a leading 0.
05843924 != 5843924
So stop being lazy with that NSNumber hacks and build your own phone-number class.
Scientific notation is used in may computer languages as the default output of very large (or very small) numbers. If you want the number to be output as a decimal, you need to specify the output format (the implementation varies by language.)
Also, julesjacobs is correct. You should not use FLOAT for a phone number as it is subject to binary rounding errors. Using INT or STRING will save you lots of headaches.
If you need to be able to deal with it as numbers maybe you should break it up into its parts, and store each part as an integer.
01112223333
country code 0
area code 111
prefix 222
number 3333
Or you could store the whole thing as a string if you don't need to manipulate it.
Are you storing a phone number in a float? You should consider using an integer or string. Perhaps:
NSNumber *inputToNumber = [NSNumber numberWithInt:[textField.text intValue]];
Hey Guys what do you think of this, It seems to full-fill my purposes. Only UK at the moment so will worry about localization when I get a chance.
I use this to get to store the number
NSNumber *inputToNumber = [NSNumber numberWithLongLong:(long long)[[textField.text stringByReplacingOccurrencesOfString:#" " withString:#""] longLongValue]];
And this method formats my telephone number and takes care of the preceeding 0 mentioned.
-(NSString *)phoneNumberString:(NSNumber *)phoneNumber {
//Add a zero because NSNumber won't save a preceeding zero
NSString *telephoneString = [[NSString alloc] initWithFormat:#"0%#", [phoneNumber stringValue]];
if (telephoneString.length >= 4) {
NSString *firstPart = [[NSString alloc] initWithString: [telephoneString substringToIndex:4]];
NSString *secondPart = [[NSString alloc] initWithString: [telephoneString substringFromIndex:4]];
//Add the two parts together with a space inbetween
NSString *formattedTelephoneString = [NSString stringWithFormat:#"%# %#", firstPart, secondPart];
//send it back to the cellForRow TableCell Method
[firstPart release];
[secondPart release];
[telephoneString release];
return formattedTelephoneString;
}
else {
return telephoneString;
}
}
Thanks for all the comments. I'm gonna mark the answer as whoever suggested NSString as I fear I will revert to using NSString for this instead of my above workaround.