# Factorials and strange rounding errors #31

Closed
opened this Issue Sep 17, 2012 · 3 comments

Projects
None yet
3 participants

### AJMiller commented Sep 17, 2012

 Hi Dave, Testing factorial math in our app, I noticed that the math parser is compiling factorials and introducing rounding errors unnecessarily. For example, the factorial of 12 is 479,001,600. If I run 12_11_10_9_8_7_6_5_4_3_2 through the math parser the result is correctly shown. If I run 12! through the parser it comes up with 479,001,599.9999997 I would normally chalk this up to doubles and computer rounding errors, but the parser is fully capable of parsing the actual factorial without any error as shown above. This leads me to suspect that the rounding error is occurring in how the parser figures out which numbers to multiply together. It is somehow figuring out the actual equation in a way that is introducing errors. All of the above math has been run through the demo project with the same result.

Owner

### davedelong commented Sep 17, 2012

 This is likely the result of using the `tgamma` function for factorial. That enables DDMathParser to support non-integral factorials. Perhaps there should be a special case for factorializing positive integers?

### AJMiller commented Sep 17, 2012

 Seems to occur with both negative and positive integers. I would gather that integer factorials would be the most common subset of factorials in general, no? Perhaps if the equation reduces down to an integer (positive or negative) it runs a simple loop?

### horaceho commented Feb 7, 2013

 As a temporary fix, I convert the result to an integral value (thus disable non-integral factorial): ``````NSNumber *result = [NSNumber numberWithDouble:tgamma([firstValue doubleValue]+1)]; NSDecimalNumber *decimal = [[NSDecimalNumber alloc] initWithDouble:result.doubleValue]; NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; NSDecimalNumber *rounded = [decimal decimalNumberByRoundingAccordingToBehavior:handler]; NSNumber *integerResult = [NSNumber numberWithDouble:rounded.doubleValue]; return [DDExpression numberExpressionWithNumber:integerResult]; ``````