2

I have got an NSString * with for example the following numbers @"182316110006010135232100" and i need to do a calculation with this complete value. I have tried multiple types of number systems on iOS SDK for example Int, Float, etc. But because of the amount of bits it changes the number when i change the StringValue to for example an IntValue. I need to do the following sum with this complete value: mod(digit, 97);

I have checked with for as far i know the longest type of number in Objective-C Long Long:

long long digit = [(NSString *)shouldBechecksum longLongValue]; 

And need to do the following calculation:

mod(digit, 97);

Now i get strange results because it does the sum with max version of the number. I need it to do this sum:

mod(182316110006010135232100, 97);

How can i do this calculation correctly?

Thanks!

4

3 回答 3

1

You can use NSDecimalNumber class for precision up to 38 digits. To obtain the mod, just use this formula with the corresponding NSDecimalNumber methods you'll find explained in the documentation.

Mod = digit - int(digit/97)

This is because NSDecimalNumber can only do the basic operations, you have to obtain the mod as we did in school.

From Apple documentation:

NSDecimalNumber, an immutable subclass of NSNumber, provides an object-oriented wrapper for doing base-10 arithmetic. An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.

于 2013-09-01T13:08:28.577 回答
0

Fixed Thanks!

NSDecimalNumber *bigDecimal = [NSDecimalNumber decimalNumberWithString:shouldBechecksum];
NSDecimalNumber *divisor = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:97] decimalValue]];
NSDecimalNumber *quotient = [bigDecimal decimalNumberByDividingBy:divisor withBehavior:[NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]];

NSDecimalNumber *subtractAmount = [quotient decimalNumberByMultiplyingBy:divisor];

NSDecimalNumber *remainder = [bigDecimal decimalNumberBySubtracting:subtractAmount];
int checkSum = 98 - [remainder intValue];
于 2013-09-01T13:11:58.667 回答
0

I have done a little test with the following code snippet:

NSString *digitStr = @"182316110006010135232100";

long long digit = [(NSString *)digitStr longLongValue];

short checksum = digit % 97;

NSLog(@"%@, %lli, %lli, %i", digitStr, LONG_LONG_MAX, digit, checksum);

The result was:

182316110006010135232100, 9223372036854775807, 9223372036854775807, 78

This means that your value passes the LONG_LONG_MAX value. So, your problem is not feasible this way.

Remark: apparently Objective C puts the value closest to your number in the variabel digit, being LONG_LONG_MAX.

I guess you will have to find some kind of solution for even longer numbers to do what you want to do. Maybe NSDecimalNumber.

Kind regards, PF

于 2013-09-01T13:15:50.540 回答