По модулю с длинными длинными целыми числами в Objective C - PullRequest
1 голос
/ 18 марта 2009

Я пытаюсь использовать оператор по модулю (%) для длинных длинных, и, похоже, он возвращает 0, если число находится выше диапазона беззнакового целого. Есть ли оператор или функция, которую я должен использовать вместо этого, или я должен свернуть свой собственный?

- Обновление: извините за отсутствие примера кода, я спешил, направляясь к двери -

Вот код:

long long val = 12345678991245; // always less than LLONG_MAX
int power = 0;
NSMutableArray *powers = [[NSMutableArray alloc] init];
while (pow(10, power) <= val) {
    tVal = (val % (lround(pow(10, power + 1)))) / lround(pow(10, power));
    [powers addObject:[NSNumber numberWithInt:tVal]];
    NSLog(@"Power: %d tVal: %d", power, tVal);
    val -= val % lround(pow(10, power + 1));
    power++;
}

Когда вы смотрите на вывод, сделанный этим оператором NSLog, вы видите это, когда число превышает UINT_MAX (для числа 1 111 111 1111 111):

2009-03-18 20:42:16.471 Numbers[11197:20b] Power: 0 tVal: 1
2009-03-18 20:42:16.472 Numbers[11197:20b] Power: 1 tVal: 1
2009-03-18 20:42:16.473 Numbers[11197:20b] Power: 2 tVal: 1
2009-03-18 20:42:16.476 Numbers[11197:20b] Power: 3 tVal: 1
2009-03-18 20:42:16.476 Numbers[11197:20b] Power: 4 tVal: 1
2009-03-18 20:42:16.477 Numbers[11197:20b] Power: 5 tVal: 1
2009-03-18 20:42:16.477 Numbers[11197:20b] Power: 6 tVal: 1
2009-03-18 20:42:16.477 Numbers[11197:20b] Power: 7 tVal: 1
2009-03-18 20:42:16.477 Numbers[11197:20b] Power: 8 tVal: 1
2009-03-18 20:42:16.478 Numbers[11197:20b] Power: 9 tVal: 0
2009-03-18 20:42:16.478 Numbers[11197:20b] Power: 10 tVal: 0
2009-03-18 20:42:16.479 Numbers[11197:20b] Power: 11 tVal: 0
2009-03-18 20:42:16.479 Numbers[11197:20b] Power: 12 tVal: 0

Все кошерно, пока вы не доберетесь до прошлого UINT_MAX, тогда оно просто возвращает 0.

Я компилирую против iPhone SDK, используя Xcode 3.1.2.

Есть идеи?

1 Ответ

4 голосов
/ 18 марта 2009

lround возвращает long, который имеет 32 бита. Попробуйте llround вместо.

Еще лучше, не используйте числа с плавающей запятой для целочисленной математики. Поскольку вы увеличиваете показатель на единицу каждый раз в цикле, вам не нужно каждый раз вычислять мощность. Просто сохраните его в переменной и умножьте на 10 на каждой итерации.

Кроме того, вместо деления числа на все более и более степенные числа десять, попробуйте делить число на десять каждый раз.

Когда вы ищете ошибку, разбейте код на более мелкие шаги и проверьте результаты промежуточных операций.

...