// GLSL Arbitrary Precision (modified a little bit) // https://github.com/alexozer/glsl-arb-prec // Number of Integers used to store an Arbitrary-Precision Number //const int n_int = 3; #define n_int 3 // Power of 10 one larger than the maximum value per int //const int limit = 10000; #define limit 32768 const float limitFlt = float(limit); int result[n_int]; #define zero(x, len) for(int i=0;i= 0; } int keepVal, carry; void roundOff(int x) { carry = x/limit; keepVal = x-carry*limit; } void add(int[n_int] a, int[n_int] b) { bool s1 = signp(a), s2 = signp(b); carry = 0; for(int i = 0; i < n_int-1; i++) { roundOff(a[i] + b[i] + carry); if(keepVal < 0) { keepVal += limit; carry--; } result[i] = keepVal; } roundOff(a[n_int-1] + b[n_int-1] + carry); result[n_int-1] = keepVal; if(s1 != s2 && !signp(result)) { negate(result); carry = 0; for(int i = 0; i < n_int; i++) { roundOff(result[i] + carry); if(keepVal < 0) { keepVal += limit; carry--; } result[i] = keepVal; } negate(result); } } void mul(int[n_int] a, int[n_int] b) { bool toNegate = false; if(!signp(a)) { negate(a); toNegate = !toNegate; } if(!signp(b)) { negate(b); toNegate = !toNegate; } const int lenProd = (n_int-1)*2+1; int prod[lenProd]; zero(prod, lenProd); for(int i = 0; i < n_int; i++) { for(int j = 0; j < n_int; j++) { prod[i+j] += a[i] * b[j]; } } carry = 0; const int clip = lenProd - n_int; for(int i = 0; i < clip; i++) { roundOff(prod[i] + carry); prod[i] = keepVal; } if(prod[clip-1] >= limit/2) { carry++; } for(int i = clip; i < lenProd; i++) { roundOff(prod[i] + carry); prod[i] = keepVal; } for(int i = 0; i < lenProd - clip; i++) { result[i] = prod[i+clip]; } if(toNegate) { negate(result); } } int[n_int] loadFloat(float f) { int x[n_int]; for(int i = n_int-1; i >= 0; i--) { int fCurr = int(f); x[i] = fCurr; f -= float(fCurr); f *= limitFlt; } return x; }