处理pascal三角形的数字溢出

我正在尝试创建一个可打印多达70行的大型pascal三角形。 我的代码一开始工作正常但是当它到达第65行时它开始打印出错误的输出。 我知道它的问题,我尝试过使用GMP。 不幸的是,我用来编码的软件不支持GMP。 有没有其他方法可以在不使用GMP的情况下实现这一目标?

char str; int value; int pascal(int n) { for (int i = 1; i < n + 2; i++) { unsigned long number = 1; for (int j = 1; j < i + 1; j++) { if(j == i) { printf("%lu\n", number); } else { printf("%lu ", number); } number = (number * (i - j) / j); } } return 0; } 

有没有其他方法可以在不使用GMP的情况下实现这一目标?

所需的整数数学在形成数字时超过基本的64位数学运算,例如109069992321755544170 ,一个67位数字,超过64个有效位。

虽然最宽的整数uintmax_t可能满足超过64位的数学需求,但它通常只有64位。

long double通常具有相当大的精度(在我的平台上只有64位),但是没有指定满足OP的需要并调用解决整数问题的FP问题。

幸运的是,所需的扩展数学只是一个乘法和除法。 简单但不高效的字符串乘法和除法满足了需要。

 void string_mult(char *y, unsigned x) { size_t len = strlen(y); unsigned acc = 0; size_t i = len; while (i > 0) { i--; acc += (y[i] - '0') * x; y[i] = acc % 10 + '0'; acc /= 10; } while (acc) { memmove(&y[1], &y[0], ++len); y[0] = acc % 10 + '0'; acc /= 10; } } unsigned string_div(char *y, unsigned x) { size_t len = strlen(y); unsigned acc = 0; for (size_t i = 0; i < len; i++) { acc *= 10; acc += y[i] - '0'; y[i] = acc / x + '0'; acc %= x; } while (y[0] == '0' && len > 1) { memmove(&y[0], &y[1], len); len--; } return acc; } void pascal(unsigned n) { printf("%u: ", n); for (unsigned i = 1; i < n + 2; i++) { char s[100] = "1"; for (unsigned j = 1; j <= i; j++) { printf("%s ", s); string_mult(s, i - j); string_div(s, j); } printf("\n"); } } int main() { for (unsigned i = 0; i <= 70; i++) pascal(i); } 

产量

 ... 1 70 2415 54740 916895 12103014 131115985 1198774720 9440350920 65033528560 396704524216 2163842859360 10638894058520 47465835030320 193253756909160 721480692460864 2480089880334220 7877932561061640 23196134763125940 63484158299081520 161884603662657876 385439532530137800 858478958817125100 1791608261879217600 3508566179513467800 6455761770304780752 11173433833219812840 18208558839321176480 27963143931814663880 40498346384007444240 55347740058143507128 71416438784701299520 87038784768854708790 100226479430802391940 109069992321755544170 112186277816662845432 109069992321755544170 100226479430802391940 87038784768854708790 71416438784701299520 55347740058143507128 40498346384007444240 27963143931814663880 18208558839321176480 11173433833219812840 6455761770304780752 3508566179513467800 1791608261879217600 858478958817125100 385439532530137800 161884603662657876 63484158299081520 23196134763125940 7877932561061640 2480089880334220 721480692460864 193253756909160 47465835030320 10638894058520 2163842859360 396704524216 65033528560 9440350920 1198774720 131115985 12103014 916895 54740 2415 70 1 

在进一步的审查中,一个long double可能会起作用,但我的努力在pascal(69)失败了pascal(69)