Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Absolute Value (abs) of NSDecimalNumber without loss of precision

Tags:

objective-c

I need to get the absolute value of an NSDecimalNumber without loss of precision. I can't seem to find a way to do this without converting to decimal or float (with a loss of precision). Is there a method to do this?

like image 249
mreith Avatar asked May 10 '09 22:05

mreith


2 Answers

You can use the built-in functions of the NSDecimalNumber class to compare the number to zero, then multiply by -1 as appropriate. For example:

- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
    if ([num compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
        // Number is negative. Multiply by -1
        NSDecimalNumber * negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
                                                                          exponent:0
                                                                        isNegative:YES];
        return [num decimalNumberByMultiplyingBy:negativeOne];
    } else {
        return num;
    }
}

Since this method works solely with NSDecimalNumbers, there's no loss of precision.

like image 181
Tim Avatar answered Nov 02 '22 18:11

Tim


There is a minor error in the answer: negativeOne should be a pointer. Here is a revised answer:

- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
    if [myNumber compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
        // Number is negative. Multiply by -1
        NSDecimalNumber *negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
                                                                    exponent:0
                                                                  isNegative:YES];
        return [num decimalNumberByMultiplyingBy:negativeOne];
    } else {
        return num;
    }
}

And here is a version suitable to be used as a category on NSDecimalNumber:

- (NSDecimalNumber *)abs {
    if ([self compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
        // Number is negative. Multiply by -1
        NSDecimalNumber *negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
                                                                         exponent:0
                                                                       isNegative:YES];
        return [self decimalNumberByMultiplyingBy:negativeOne];
    } else {
        return self;
    }
}
like image 9
mts Avatar answered Nov 02 '22 17:11

mts