A vote for option to use NSDecimalNumbers #28

Closed
AJMiller opened this Issue Aug 28, 2012 · 11 comments

Projects

None yet

6 participants

@AJMiller

Hey Dave,

I know there is probably a reason why you abandoned the NSDecimal type, but these floating point rounding errors seem like a pretty big sacrifice. Having a user add 44.19 + 53.71 is resulting in 97.9000000001. It seems to be proving difficult for me to format this back to 97.9 without some very hacky solutions. It seems for a class that is designed to perform calculations that NSDecimal (or at least an option for developers to enable NSDecimal generated answers) is a logical choice. Is it possible to have a BOOL that could determine whether or not NSDecimals are used under the hood for those of us trying to display and work with the answers that DDMathParser produces?

@tony-karandeev

Yep, it would be nice to have an option to use decimal arithmetics, it's kind of necessary when you need to display result with nice formatting.

BTW, you've done great job, thank you!

@davedelong
Owner

I'll look in to it.

@AJMiller
AJMiller commented Oct 4, 2012

Hi Dave,

Any update on this? We have been getting a steady flow of bug requests from our users about various arithmetic problems (i.e. 57.98 - 58.10) that are resulting in floating point rounding errors. Even the built in osx calculator is able to overcome/mask these errors, so it's difficult to justify to our users that 'all calculators do this'. I have been working on trying to implement an nsdecimal option myself, but without a deep understanding of the framework it's proving to be difficult. If there are other ways to circumvent these errors, I would be very interested in hearing! Thanks for a great framework. We are hoping to implement it in various projects but need to make sure the output is as accurate as possible.

@davedelong davedelong was assigned Oct 4, 2012
@dinocol
dinocol commented Oct 17, 2012

Hi Dave, thanks a lot for the great job! :) hope you would still continue to support this project..

@AJMiller i also encountered the same problem, please try this, i hope there won't be any errors that will show up after modifying this part of the code

_DDFunctionUtitilies.m

in the addfunction part

DDMathFunction function = ^ DDExpression* (NSArray *arguments, NSDictionary *variables, DDMathEvaluator *evaluator, NSError **error) {
    REQUIRE_N_ARGS(2);
    NSNumber * firstValue = [[arguments objectAtIndex:0] evaluateWithSubstitutions:variables evaluator:evaluator error:error];
    RETURN_IF_NIL(firstValue);

    NSNumber * secondValue = [[arguments objectAtIndex:1] evaluateWithSubstitutions:variables evaluator:evaluator error:error];
    RETURN_IF_NIL(secondValue);


    //NSNumber *result = [NSNumber numberWithDouble:[firstValue doubleValue] + [secondValue doubleValue]];

    NSDecimalNumber *num1 = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%@",firstValue]];
    NSDecimalNumber *num2 = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%@",secondValue]];
    NSDecimalNumber *result =[num1 decimalNumberByAdding:num2];


    return [DDExpression numberExpressionWithNumber:result];
};
return DD_AUTORELEASE([function copy]);
@AJMiller

@dinocol Thanks for the reply. The problem I'm having is little more widespread. I'm getting rounding errors on many functions. What we ended up doing is running all formatting through an NSNumberFormatter and set the max fraction digits to 14. That effectively eliminated the rounding errors and since doubles aren't accurate much beyond 14 digits anyways, we aren't really losing anything. Hopefully this will help others struggling with the same issue.

@davedelong
Owner

As an update, I've started working on this. We'll see how it goes.

@AJMiller

Sounds great. Thanks Dave! Looking forward to the update!!!

@horaceho
horaceho commented Jan 7, 2013

As a quick fix, I format the result to 2 decimal places in my calculator, i.e.:

- (NSString *)formatResult:(NSString *)value
{
    NSUInteger fractionDigits = 2;
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [formatter setMaximumFractionDigits:fractionDigits];
    [formatter setRoundingMode: NSNumberFormatterRoundUp];
    NSString *result = [formatter stringFromNumber:[NSNumber numberWithDouble:value.doubleValue]];
    return result;
}
@alessiomaffeis

Is there any update on this issue?

@davedelong
Owner

The changes I just pushed have re-added support for NSDecimal-based math. There's a new property: DDMathEvaluator.usesHighPrecisionEvaluation (which defaults to NO). It's largely experimental, but it's there.

@davedelong davedelong closed this Jan 4, 2014
@AJMiller
AJMiller commented Jan 4, 2014

Awesome. Thanks Dave. Can’t wait to check it out!

Sincerely,

AJ Miller
amillerjr@gmail.com

On Jan 4, 2014, at 12:41 PM, Dave DeLong notifications@github.com wrote:

The changes I just pushed have re-added support for NSDecimal-based math. There's a new property: DDMathEvaluator.usesHighPrecisionEvaluation (which defaults to NO). It's largely experimental, but it's there.


Reply to this email directly or view it on GitHub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment