JKBigInteger
JKBigInteger copied to clipboard
Fatal Error: JKBigDecimal Internal Logic Mutates Variables
While performing some functions, sometimes the internal logic of the library will mutate values we were working with, this was leading to fatal errors in our system
One isolated example is here:
+(void)load {
#define jkCopy(__jk) __jk//[JKBigDecimal decimalWithString:[(__jk) stringValue]]
JKBigDecimal *tcc = [JKBigDecimal decimalWithString:[NSString stringWithFormat:@"%i", (int)pow(2, 13)]];
JKBigDecimal *rbc = [JKBigDecimal decimalWithString:[NSString stringWithFormat:@"%i", (int)pow(2, 21)]];
JKBigDecimal *HPS = [JKBigDecimal decimalWithString:[NSString stringWithFormat:@"%f", 500000.0]];
JKBigDecimal *btwt = [jkCopy(rbc) divide:jkCopy(HPS)];
JKBigDecimal *btwot = [jkCopy([jkCopy(rbc) multiply:jkCopy(tcc)]) divide:jkCopy(HPS)];
NSLog(@"btwt = %@", [btwt stringValue]);//logs 4 correctly
NSLog(@"btwt/2 = %@", [[jkCopy(btwt) divide:[JKBigDecimal decimalWithString:@"2.0"]] stringValue]);
NSLog(@"btwt = %@", [btwt stringValue]);//logs 40 incorrectly, btwt was mutated! Fatal error
exit(0);
}
As you can see, the variable btwt
changes from 4 to 40 at the end even though we did not mutate it in our code (it was mutated internally by a bug in JKBigDecimal)
I created a macro jkCopy()
to make a new version of each JKBigDecimal value each time to prevent the mutation from impacting other areas of code, this copy macro is disabled in the code above but you can un-comment it back in to see it fix and give the expected output value in logs.