changing a string to double returning one - objective-c

I have stored a value 1/129600.0 in a plist as a string.
I am able to retrieve it as a string but when i am trying to convert it as a double i am getting it as 1.0.I have also tried CFString
NSString *value = [[self array]objectAtIndex:m];
double a = [value doubleValue];
NSLog(#"%#",value);
NSLog(#"%f",a);
and in log the returned values are
1/129600.0 and 1.0

This code works fine, I tried it in xCode:
NSString *equation = [[self array]objectAtIndex:m];
NSExpression *result = [NSExpression expressionWithFormat:equation];
NSNumber *a = [result expressionValueWithObject:nil context: nil];
NSLog(#"%#",result);
NSLog(#"%.10f",[a doubleValue]);

I guess 1/129600.0 is not a valid number.
Try to create an expression and create an NSNumber from it:
NSString *equation = [[self array]objectAtIndex:m];
NSNumber *a = [[NSExpression expressionWithFormat:equation] expressionValueWithObject:nil context:nil];
double a = [result doubleValue];
NSLog(#"%f", a);

1/129600.0 is not a valid representation for a number in most programming languages, including ObjC. You need to parse the string and interpret it yourself.

Try this
NSString *value = [[self array]objectAtIndex:m];
NSArray *arr = [value componentsSeparatedByString:#"/"];
double a;
if ([arr count] == 2)
{
a = [arr objectAtIndex:0]/[arr objectAtIndex:1];
}
NSLog(#"%#",value);
NSLog(#"%f",a);

Related

Comparing NSDecimalNumber won't work?

For some reason, the comparing logic isn't working correctly... it wont compare two NSDecimalNumber objects. Sometimes it works, sometimes it doesn't. Really weird. The if statement works on some compilations, and sometimes not. Is this the right way of doing it?
The data is from a json file which is a 2 point decimal number which looks like this: 63.32
Why isn't this working correctly?
NSError * error;
NSDictionary * json = [NSJSONSerialization JSONObjectWithData:responceData options:kNilOptions error:error];
NSArray * latestPrice = [json objectForKey:#"data"];
NSLog(#"Latest price %#", latestPrice);
NSNumber * value = [(NSDictionary*)[latestPrice objectForKey:#"last_offer"] objectForKey:#"display"];
NSString * val = [[NSString alloc] initWithFormat:#"%#", value];
NSString * valFinal = [val stringByTrimmingCharactersInSet:[NSCharacterSet symbolCharacterSet]];
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:valFinal];
NSLog(#"%#", number);
NSString * val2 = [[NSString alloc] initWithString:#"44.14"];
NSDecimalNumber *number2 = [NSDecimalNumber decimalNumberWithString:val2];
if(number2 >= number){
NSLog(#"ds");
}
I need to compare the json value with a local value with the same decimal points.
NSDecimalNumber is an object. You tried to compare memory addresses.
Use compare: instance method of NSDecimalNumber.
if ([number compare:number2] == NSOrderedAscending)
NSDecimalNumber Class Reference

Make variable name out of NSString

I have got a for loop where 9 hexagons (hexagon1 through hexagon9) have to be created... But I cannot use hexString as the name of the Sprite because it is a NSString, right ? So how would I make it right ?
hexString [<- I want the for loop to generate "hexagon1", then "hexagon2" and so on instead of the NSString] = [self createHexagon:ccp(xVal,yVal) :i];
int hexCount = [[[itemPositions valueForKey:myString]valueForKey:#"hexposition"] count];
for (int i=1;i<=hexCount;i++){
NSString *hexString = [NSString stringWithFormat:#"hexagon%d",i];
NSNumber *generatedXVal = [[[[itemPositions valueForKey: myString ]valueForKey:#"hexposition"] valueForKey: hexString]valueForKey: #"xVal"];
int xVal = [generatedXVal integerValue];
NSNumber *generatedYVal = [[[[itemPositions valueForKey: myString ]valueForKey:#"hexposition"] valueForKey: hexString ]valueForKey: #"yVal"];
int yVal = [generatedYVal integerValue];
hexString = [self createHexagon:ccp(xVal,yVal) : i];
NSLog(#"%#", hexString);
}
That would be impossible as you didn't declare the variable. A work around for this would be using an NSArray and saving your data on to the array instead of making a list of variables.
Use NSMutableDictionary.
for (int i=1;i<=hexCount;i++){
NSString *hexString = [NSString stringWithFormat:#"hexagon%d",i];
CCSprite *sprite = [self doSomethingToGetSprite];
[mutableDictionary setObject:sprite forKey:hexString];
}
Later you can iterate over all the sprites in the dictionary using:
for (NSString *key in mutableDictionary) {
CCSprite *sprite = [mutableDictionary objectForKey:key];
[self doStuffWithSprite:sprite];
}
By the way, why are you overwriting hexString that you assign here:
NSString *hexString = [NSString stringWithFormat:#"hexagon%d",i];
With the one here:
hexString = [self createHexagon:ccp(xVal,yVal) : i];
And that method call is an obvious syntax error with the dangling : i part there.
can you use NSSelectorFromString?

EXC_BAD_ACESS error

I get that error EXC_BAD_ACESS at the following line:
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionTitle",i];
Here is the for loop where the above code line is located:
for (i=0; i < count; ++i)
{
//Save the occasionS details to NSUserDefaults
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionTitle",i];
NSString *dateVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionDate",i];
NSString *imageVarName = [[NSString alloc] initWithFormat:#"%#%#",#"occasionImage",i];
[[NSUserDefaults standardUserDefaults] setValue:[[[self displayedObjects] objectAtIndex:i]
title] forKey:titleVarName];
[[NSUserDefaults standardUserDefaults] setValue:[[[self displayedObjects] objectAtIndex:i]
date] forKey:dateVarName];
[[NSUserDefaults standardUserDefaults] setValue:[[[self displayedObjects] objectAtIndex:i]
imagePath] forKey:imageVarName];
//release
[titleVarName release];
[dateVarName release];
[imageVarName release];
[self dismissModalViewControllerAnimated:YES];
}
Isn't ok to alloc objects and release them inside a for loop?
You need to use %d or %i specifier instead of %# to specify an integer. If %# is used with int then it will try to access the object at the address specified by the int. For example, if the value of i is one then it is trying to access the object at address one which will cause a bad access.
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%d",#"occasionTitle",i];
And also you don't need alloc and release here, though that is not the reason of bad access. You can use a convenience constructor.
NSString *titleVarName = [NSString stringWithFormat:#"occasionTitle%d", i];
// release not required
Do the same for dateVarName and imageVarName too.
Assuming i is an int, that line should be
NSString *titleVarName = [[NSString alloc] initWithFormat:#"%#%i",#"occasionTitle",i];
%# is used for Cocoa objects, not primitives like an int, float or bool;
Use the %# format specifier only for NSObject objects.
As i is an integer in your code, you have to use %d or %i for integers.
Moreover, there is no need to include the string using %#, you can use the static string directly in your format string:
NSString *titleVarName = [[NSString alloc] initWithFormat:#"occasionTitle%i",i];

Obj-C: Calculate the standard deviation of an NSArray of NSNumber objects?

If I have an NSArray of NSNumber objects, how do I calculate the standard deviation of the numbers in the array?
Assuming it's safe to process all NSNumbers as double length floats (so you'll lose some precision if you've got some 64 bit integers at extreme ends of the range in there) and I've remembered the formula correctly a first implementation could be:
- (NSNumber *)meanOf:(NSArray *)array
{
double runningTotal = 0.0;
for(NSNumber *number in array)
{
runningTotal += [number doubleValue];
}
return [NSNumber numberWithDouble:(runningTotal / [array count])];
}
- (NSNumber *)standardDeviationOf:(NSArray *)array
{
if(![array count]) return nil;
double mean = [[self meanOf:array] doubleValue];
double sumOfSquaredDifferences = 0.0;
for(NSNumber *number in array)
{
double valueOfNumber = [number doubleValue];
double difference = valueOfNumber - mean;
sumOfSquaredDifferences += difference * difference;
}
return [NSNumber numberWithDouble:sqrt(sumOfSquaredDifferences / [array count])];
}
You can use NSExpression built-in functions.
NSArray *numbers = #[#1, #2, #3, #4, #5, #6, #7, #8];
NSExpression *expression = [NSExpression expressionForFunction:#"stddev:" arguments:#[[NSExpression expressionForConstantValue:numbers]]];
NSNumber *value = [expression expressionValueWithObject:nil context:nil];
NSLog(#"%#,", value); // => 2.29128...
For more information check the official documentation and this NSHipster article.
Here a category for NSArray to facilitate similar tasks, using NSExpression, similar to Tiago's method. You can pass it any NSExpression that you wish to calculate as string (colon is added in the function).
#interface NSArray (Stats)
- (NSNumber *)calculateStat:(NSString *)stat;
#end
#implementation NSArray (Stats)
- (NSNumber *)calculateStat:(NSString *)stat
{
NSArray *args = #[[NSExpression expressionForConstantValue:self]];
NSString *statFormatted = [stat stringByAppendingString:#":"];
NSExpression *expression = [NSExpression expressionForFunction:statFormatted arguments:args];
return [expression expressionValueWithObject:nil context:nil];
}
#end
Use like so:
NSNumber *result = [myArray calculateStat:#"stddev"];
Here's a link to an algorithm you could use. I don't know of any built-in Objective C statistics libraries, so I would just implement the algorithm myself. The link does it in Java, but it should be easy to convert.
There is some good code on Rosetta Code for this. To go through your NSArray (instead of C array like they have in their example), just use this code along with their implementation of SDAccum:
- (double)computeStandardDeviationWithArray:(NSArray *)numberArray
{
double sd;
SDAccum *sdacc = [[SDAccum alloc] init];
for(NSNumber *aNumber in numberArray)
{
sd = [sdacc value: [aNumber doubleValue]];
}
[sdacc release];
return sd;
}
Here is another version I've used some time ago.
NSArray *numbers = [NSArray arrayWithObjects:[NSNumber numberWithInt:...],
[NSNumber numberWithInt:...],
[NSNumber numberWithInt:...], nil];
// Compute array average
int total = 0;
int count = [numbers count];
for (NSNumber *item in numbers) {
total += [item intValue];
}
double average = 1.0 * total / count;
// Sum difference squares
double diff, diffTotal = 0;
for (NSNumber *item in numbers) {
diff = [item doubleValue] - average;
diffTotal += diff * diff;
}
// Set variance (average from total differences)
double variance = diffTotal / count; // -1 if sample std deviation
// Standard Deviation, the square root of variance
double stdDeviation = sqrt(variance);

How to convert NSNumber to NSString

So I have an NSArray "myArray" with NSNumbers and NSStrings. I need them in another UIView so i go like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *details = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
details.subjectText = [[myArray objectAtIndex:indexPath.row] objectForKey:#"subject"];
The subjectText works.
But how can I get the NSNumbers out of it? (I actually need them as strings...)
I would convert a NSString out of a NSNumber like this:
NSString *blah = [NSNumber intValue]. But I don't know how to set it up in the code above...
Try:
NSString *myString = [NSNumber stringValue];
You can do it with:
NSNumber *myNumber = #15;
NSString *myNumberInString = [myNumber stringValue];
//An example of implementation :
// we set the score of one player to a value
[Game getCurrent].scorePlayer1 = [NSNumber numberWithInteger:1];
// We copy the value in a NSNumber
NSNumber *aNumber = [Game getCurrent].scorePlayer1;
// Conversion of the NSNumber aNumber to a String with stringValue
NSString *StringScorePlayer1 = [aNumber stringValue];
or try NSString *string = [NSString stringWithFormat:#"%d", [NSNumber intValue], nil];
The funny thing is that NSNumber converts to string automatically if it becomes a part of a string. I don't think it is documented.
Try these:
NSLog(#"My integer NSNumber:%#",[NSNumber numberWithInt:184]);
NSLog(#"My float NSNumber:%#",[NSNumber numberWithFloat:12.23f]);
NSLog(#"My bool(YES) NSNumber:%#",[NSNumber numberWithBool:YES]);
NSLog(#"My bool(NO) NSNumber:%#",[NSNumber numberWithBool:NO]);
NSString *myStringWithNumbers = [NSString stringWithFormat:#"Int:%#, Float:%# Bool:%#",[NSNumber numberWithInt:132],[NSNumber numberWithFloat:-4.823f],[NSNumber numberWithBool:YES]];
NSLog(#"%#",myStringWithNumbers);
It will print:
My integer NSNumber:184
My float NSNumber:12.23
My bool(YES) NSNumber:1
My bool(NO) NSNumber:0
Int:132, Float:-4.823 Bool:1
Works on both Mac and iOS
This one does not work:
NSString *myNSNumber2 = [NSNumber numberWithFloat:-34512.23f];
In Swift you can do like this
let number : NSNumber = 95
let str : String = number.stringValue
In Swift 3.0
let number:NSNumber = 25
let strValue = String(describing: number as NSNumber)
print("As String => \(strValue)")
We can get the number value in String.