Why does NSNumberFormatter not accept plus number - ios

if(![myNumberFormatter numberFromString:[tempColumn objectAtIndex:j]])
{
numericalColumns[j] = NO;
if(j == 8)
{
NSLog(#" non numerical value in column 8 i = %d object = %# ", i , [tempColumn objectAtIndex:j]);
}
}
What I find:
0 good
-19.49883745 good
+38.85928608 bad
+46.94000154 bad
-0.36042119 good
+38.30408636 bad
-44.29029741 good
+26.91823821 bad
-79.06183133 good
-16.69693020 good

Try doing this:
[myNumberFormatter setPositivePrefix:#"+"];
before calling numberForString

Related

how does the pow function work?

I am looking to write my own power function to work with NSDecimalNumbers and exponents that are not whole numbers. I first tried to use a combination of newtons method and the built in integer power method, but due to newtons method i am getting overflow errors when I have exponents with more than 2 decimals. So I thought maybe the float value pow function might serve as a good model for my own function. So I was wondering if anyone knows where I can fond some sort of documentation on the inner workings of the pow function?
Edit:
#wombat57, those links look like they could be what I am looking for however I have no idea to read them. The algorithm you suggest is in fact what I am using. the overflow comes from newtons method due to very large exponents. Because I am getting exponents in decimal form I have to convert it to a fraction first. the only way of ding this in code, as far as I know, multiplying the decimal by ten until you have a whole number, and using that as the numerator. Doing this you get exponents of 100+ for numbers with 3 or more decimals. this causes an overflow error.
EDIT 1: Here are links to the actual source
http://opensource.apple.com/source/Libm/Libm-2026/Source/Intel/expf_logf_powf.c
http://opensource.apple.com/source/Libm/Libm-315/Source/ARM/powf.c
I got the links from this question, which has a bunch of relevant discussion
self made pow() c++
This page describes an algorithm: Link.
x^(1/n) = the nth root of x, and x^mn = (x^m)^n. Thus, x^(m/n) = (the nth root of x)^m. Arbitrary roots can be calculated with Newton's method. Integer powers can be calculated with Exponentiation by squaring. For irrational exponents, you can use increasingly accurate rational approximations until you get the desired number of significant digits.
EDIT 2:
Newton's method involves raising your current guess to the power of the root that you're trying to find. If that power is large, and the guess is even a little too high, this can result in overflow. One solution here is to identify this case. If overflow ever occurs, this means that the guess was too high. You can solve the problem by (whenever a guess results in overflow), setting the current guess to a value between the last guess that did not overflow and the current guess (you may have to do this several times). That is, whenever Newton's method overflows, do a binary search down toward the last guess that did not overflow. Here's some python that implements all of this:
def nroot(n, b, sig_figs = 10):
g1 = 1.0
g2 = 1.0
while True:
done = False
while not done:
try:
g3 = g2 - ((g2**b) - n) / (b * (g2**(b-1)))
done = True
except OverflowError:
g2 = (g1 + g2) / 2.0
if abs(g2 - g3) < 1.0 / (10**sig_figs):
return g3
g1 = g2
g2 = g3
def npowbysqr(n, p):
if p == 0:
return 1.0
if p % 2 == 0:
v = npowbysqr(n, p/2)
return v*v
else:
return n*npowbysqr(n, p-1)
def npow(n, p):
return npowbysqr(nroot(n, 1000000), int(p*1000000))
print npow(5, 4.3467)
print 5**4.3467
I should add that there are probably much better solutions. This does seem to work, however
I happened to need something like this a while ago. Thankfully, Dave DeLong had been tinkering with this in his DDMathParser, so I built off of that. He yanked his implementation from his code in this commit, but I took that and modified it. This is my version of his NSDecimal power function:
extern NSDecimal DDDecimalPower(NSDecimal d, NSDecimal power) {
NSDecimal r = DDDecimalOne();
NSDecimal zero = DDDecimalZero();
NSComparisonResult compareToZero = NSDecimalCompare(&zero, &power);
if (compareToZero == NSOrderedSame) {
return r;
}
if (DDDecimalIsInteger(power))
{
if (compareToZero == NSOrderedAscending)
{
// we can only use the NSDecimal function for positive integers
NSUInteger p = DDUIntegerFromDecimal(power);
NSDecimalPower(&r, &d, p, NSRoundBankers);
}
else
{
// For negative integers, we can take the inverse of the positive root
NSUInteger p = DDUIntegerFromDecimal(power);
p = -p;
NSDecimalPower(&r, &d, p, NSRoundBankers);
r = DDDecimalInverse(r);
}
} else {
// Check whether this is the inverse of an integer
NSDecimal inversePower = DDDecimalInverse(power);
NSDecimalRound(&inversePower, &inversePower, 34, NSRoundBankers); // Round to 34 digits to deal with cases like 1/3
if (DDDecimalIsInteger(inversePower))
{
r = DDDecimalNthRoot(d, inversePower);
}
else
{
double base = DDDoubleFromDecimal(d);
double p = DDDoubleFromDecimal(power);
double result = pow(base, p);
r = DDDecimalFromDouble(result);
}
}
return r;
}
It tries to identify common cases and use more precise calculations for those. It does fall back on pow() for things that don't fit in these cases, though.
The rest of the NSDecimal functions I use can be found here and here.
I have come up with a function that suits my needs and will hopefully suit the needs of many others. the following method is fully annotated and works for any power function that has a real value. This method also only uses NSDecimalNumbers meaning you will not loose any precision due to float rounding error. This method takes two arguments one for the base and one for the power, and both are NSDecimalNumbers. So here it is:
//these are constants that will be used
NSDecimalNumber *ten = [NSDecimalNumber decimalNumberWithString:#"10"];
NSDecimalNumber *one = NSDecimalNumber.one;
//these will together hold the power in fractional form
NSDecimalNumber *numerator = power, *denominator = one;
//this will hold the final answer and all previous guesses the first guess is set to be the base
NSDecimalNumber *powAns = base;
//this will hold the change in your guess, also serves as an idea of how large the error is
NSDecimalNumber *error = one;
//part1 holds f(x) and part2 holds f'(x)
NSDecimalNumber *part1, *part2;
//if the base is < 0 and the power is not whole, answer is not real
if ([base doubleValue] < 0 && [[power stringValue] rangeOfString:#"."].location != NSNotFound)
return NSDecimalNumber.notANumber;
//converts power to a fractional value
while ([[numerator stringValue] rangeOfString:#"."].location != NSNotFound) {
numerator = [numerator decimalNumberByMultiplyingBy:ten];
denominator = [denominator decimalNumberByMultiplyingBy:ten];
}
//conditions here are the precision you wish to get
while ([error compare:[NSDecimalNumber decimalNumberWithString:#"1e-20"]] == NSOrderedDescending ||
[error compare:[NSDecimalNumber decimalNumberWithString:#"-1e-20"]] == NSOrderedAscending) {
//if this catches an overflow error it is set to be a very large number otherwise the value cannot be a number, however no other error should be returned.
#try {
part1 = [powAns decimalNumberByRaisingToPower:[denominator intValue]];
}
#catch (NSException *exception) {
if ([exception.name isEqual: NSDecimalNumberOverflowException])
part1 = [NSDecimalNumber decimalNumberWithString:#"10e127"];
else
return NSDecimalNumber.notANumber;
}
part1 = [part1 decimalNumberBySubtracting:base];
//if this catches an overflow error it is set to be a very large number otherwise the value cannot be a number, however no other error should be returned.
#try {
part2 = [powAns decimalNumberByRaisingToPower:[denominator intValue]-1];
part2 = [part2 decimalNumberByMultiplyingBy:denominator];
}
#catch (NSException *exception) {
if ([exception.name isEqual: NSDecimalNumberOverflowException])
part2 = [NSDecimalNumber decimalNumberWithString:#"10e127"];
else
return NSDecimalNumber.notANumber;
}
//error is the change in the estimated value or y - f(x)/f'(x)
error = [part1 decimalNumberByDividingBy:part2];
powAns = [powAns decimalNumberBySubtracting: error];
}
//if the numerator value is negative it must be made positive and the answer is then inverted
if ([numerator intValue] < 0) {
powAns = [powAns decimalNumberByRaisingToPower:abs([numerator intValue])];
powAns = [one decimalNumberByDividingBy:powAns];
}
else
powAns = [powAns decimalNumberByRaisingToPower:[numerator intValue]];
return powAns;
If anyone has any questions about my code I am happy to answer them.

Checking that String has a valid number

I'm a programming newbie and I'm currently writing a conversion calc program in objective c and I'm really struggling.
I have a string representing a unsigned long long value. I need a way either when attempting to add another character to check that the new character would not go above LONG_LONG_MAX before adding it. Or deleting the last character if the value is/would be above LONG_LONG_MAX
the only possible way I could think to even try this is:
- (BOOL) isNumberStringValid:(NSString *)stringValue {
unsigned long long uVal = strtoull(stringValue.UTF8String, NULL, 0);
if (uVal <= ULLONG_MAX) return TRUE;
else return FALSE;
}
I know this doesn't work because uVal would always be <= ULLONG_MAX but I can't think of any other ways to possibly check. Can anyone help me find a way to accomplish this???
You can use the fact that strtoull() sets the value of errno to ERANGE if the given
string was out of range:
- (BOOL) isNumberStringValid:(NSString *)stringValue {
errno = 0;
unsigned long long uVal = strtoull(stringValue.UTF8String, NULL, 0);
return (errno == 0);
}
Some test (ULLONG_MAX = 264-1 = 18446744073709551615):
1234 : TRUE
18446744073709551615 : TRUE
18446744073709551616 : FALSE
1844674407370955161678 : FALSE
You can use NSNumberFormatter. Unfortunately NSNumberFormatter stores the 'maximum' value as a float, so there are some problems around the boundary of LONG_LONG_MAX. To deal with that this code checks for nil or a long long value that is negative (which means that it overflowed)
-(BOOL) isNumberStringValid:(NSString *)stringValue
{
[NSNumberFormatter setDefaultFormatterBehavior:NSNumberFormatterBehavior10_4];
NSNumberFormatter *f=[[NSNumberFormatter alloc]init];
NSNumber *max=[NSNumber numberWithLongLong:LONG_LONG_MAX];
[f setMaximum:max];
BOOL valid=NO;
NSNumber *num=[f numberFromString:stringValue];
if (num != nil) // A nil value means that input was > LONG_LONG_MAX
{
long long x=[num unsignedLongLongValue]; // A negative value here means that the input was > LONG_LONG_MAX
if (x>0)
{
valid=YES;
}
}
return valid;
}
the if statement you have is checking if uVal is less than or equal to LONG_LONG_MAX
unsigned long long uVal = (unsigned)stringValue.longLongValue;
if (uVal >= LONG_LONG_MAX) {
return YES;
}
else {
return NO;
}
I ran this and it works fine.

IOS String length comparison issue

I'm struggling with an if Comparison - I basically want to make two comparisons - both of which need to pass - Firstly a basic if a string variable is equal to 'rec' and secondly if a strings character limit is not equal to zero.
I've tried various combinations - but this is where i'm at at the mo..
ArticleObject *A = [self.articleArray objectAtIndex:indexPath.section];
NSInteger imglength = [A.arImage length];
if([A.arRec isEqual: #"rec"] ) && (imglength !=Nil){
return 195;
}
else return 50;
I get an expected identifier error on the (imglength comparison - as in this screen shot
Can anyone shed any light for me please?
There are several things you should change:
ArticleObject *A = self.articleArray[indexPath.section];
NSInteger imglength = [A.arImage length];
if (imglength && [A.arRec isEqualToString:#"rec"]) {
return 195;
} else {
return 50;
}
Don't use Nil (or nil) with primitive types.
Your parentheses are messed up:
if([A.arec isEqualToString:#"rec"] && (imglengyb !=Nil))
^--------------//here
Maybe a better way would be:
if([A.arec isEqualToString:#"rec"] && [[A.arImage length] != 0])

iOS Fastest method to extract a substring

I have several thousand strings in the form "verb-noun" for which I want to extract the noun portion. I am looking for the FASTEST way to do this. The verb and noun portions can be any length.
I have tried
NSString *noun = [[verb componentsSeparatedByString:#"-"] lastObject];
Which is slow... For my list of over 3000 entries it takes about 3 seconds.
Also tried
NSString *noun = [verb substringFromIndex:[verb rangeOfString:#"-"].location + 1];
which is MUCH faster, about a half second.
Anyone have suggestions for making this even faster?
If your work with these strings is thread-safe then one option is to use GCD to iterate over multiple verb values simultaneously, bringing multiple cores into action. Use dispatch_apply instead of whatever loop you're using, something like:
dispatch_apply([myWordArray count], queue, ^(size_t i) {
NSString *verb = [myWordArray objectAtIndex:i];
NSString *noun = [verb substringFromIndex:[verb rangeOfString:#"-"].location + 1];
// do something with noun...
});
Just keep in mind that this will do more than one pass simultaneously, so be very sure about threading issues.
Fastest way would probably to sort the most likely cases for where the hyphen is, and then check for those first without using a loop. For example, if the most likely cases for index of hyphen are 5, 4, 6, 7, 3, 2 in that order, you could do this:
NSString * verb = #"verb-noun";
NSString * noun = nil;
//use do...while(0) to avoid nested if else
do
{
if([verb characterAtIndex:5] == '-')
{
noun = [verb substringFromIndex:6];
break;
}
if([verb characterAtIndex:4] == '-')
{
noun = [verb substringFromIndex:5];
break;
}
if([verb characterAtIndex:6] == '-')
{
noun = [verb substringFromIndex:7];
break;
}
if([verb characterAtIndex:7] == '-')
{
noun = [verb substringFromIndex:8];
break;
}
if([verb characterAtIndex:3] == '-')
{
noun = [verb substringFromIndex:4];
break;
}
if([verb characterAtIndex:2] == '-')
{
noun = [verb substringFromIndex:4];
break;
}
} while(0);
//if not one of most likely cases, loop
if(!noun)
{
for(int j = 8; j < verb.length; j++)
{
if([verb characterAtIndex:j] == '-')
{
noun = [verb substringFromIndex:j + 1];
break;
}
}
}
if(noun)
{
//noun should never be nil
NSLog(#"found the noun");
}

creating a prefix NSString using two NSStrings

I have instructions to make a prefix method that takes two strings for each position where mask = 0 and the first string = second string up until these conditions are not meet that is your prefix NSString.
I made my attempt but for some reason my prefix string is returning as null and I was hoping i could get some help.
here is my method
- (void)prefixCalculation:(NSString *)seriesStart SeriesEnd:(NSString *)seriesEnd {
// call this method when loading the view to get everything set up
NSLog(#"start %#", seriesStart);
NSLog(#"end %#", seriesEnd);
// allocate values so you can use this to create the UITextField
seriesStartString = seriesStart;
seriesEndString = seriesEnd;
// set prefix string
for (int i = 0; i <= seriesStartString.length ; i++) {
unichar c1 = [seriesStartString characterAtIndex:i];
unichar c2 = [seriesEndString characterAtIndex:i];
if (c1 != c2) {
break;
}
else if (c1 == c2) {
NSString *str = [NSString stringWithFormat: #"%C", c1];
[prefixString appendFormat:#"%#",str];
}
}
NSLog(#"prefix %#", prefixString);
}
I am not sure what I am doing wrong but prefixString which is a NSMutableStrong comes back as null, any help would be greatly appreciated.
Since in your code you don't show the initialization of prefixString, I take a guess and suggest you to check whether you initialized it or not.
If that's not the case, prefixString is nil and sending messages to it will fail silently.

Resources