Tratamiento del desbordamiento numérico para triángulo pascal.

Estoy intentando crear un triángulo pascal grande que imprime hasta 70 líneas. Mi código funciona bien al principio, pero comenzó a imprimir la salida incorrecta cuando llega a la línea 65. Conozco el problema y he intentado usar GMP. Desafortunadamente, el software que utilizo para codificar no es compatible con GMP. ¿Hay alguna otra forma en que pueda hacer esto sin usar 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; } 

¿Hay alguna otra forma en que pueda hacer esto sin usar GMP?

La matemática de enteros necesaria excede la matemática básica de 64 bits para formar números como 109069992321755544170 , un número de 67 bits con más de 64 bits significativos iniciales.

Aunque el entero más amplio uintmax_t puede satisfacer las necesidades matemáticas de más de 64 bits, generalmente solo es de 64 bits.

long double menudo tiene una gran cantidad de precisión (solo de 64 bits en mi plataforma), pero eso no está especificado para satisfacer las necesidades de OP e invoca los problemas de FP de resolver un problema de enteros .

Afortunadamente, la matemática extendida necesaria es solo una multiplicación y división. Una cadena simple, aunque no altamente eficiente, se multiplica y divide para satisfacer la necesidad.

 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); } 

Salida

 ... 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 

En una revisión adicional, un long double puede funcionar, pero mis esfuerzos fracasaron en pascal(69) .