iOS : unsigned long with big factorial

iOS : unsigned long with big factorial

我正在尝试使用如下的阶乘方法

-(void)getFactorial{
    NSString *numStr = [NSString stringWithFormat:@"%@", _maxTF.text];
    max = strtoull([numStr UTF8String], NULL, 0);
    for (unsigned long i = 1; i< max ; i++) {
        unsigned long factorial = [self factorial:i];
       if(factorial <= max){
          NSLog(@"%lu (%lu!  =  %lu)",i ,i ,factorial);
       }else{
          break;
       }
    }
}

-(unsigned long) factorial:(unsigned long)n
{
    if (n==0) {
        return 1;//TODO make it empty
    }
    else
    {
        return n*[self factorial:n-1];
    }
}

它很简单而且工作正常..直到我尝试像 (18446744073709551615) 这样的数字 当 i = 20 时一定会停止,但 21 的阶乘实际上小于 20 的阶乘,因此它会一直持续到达到零。

我想不通到底是哪里出了问题。

因为您使用的是未签名的值,所以乘法会导致溢出。这就是为什么21!看起来不到20!在您的申请中。

log2(21!) = 65.4,所以无符号数学只是丢掉高位。

阶乘大于 usigned long 允许的值,导致溢出(再次从 0 开始)使其看起来更小。