import { assert } from 'chai'; import { expansionProduct, eAbs, eCompress, eSum, eDiff, isNonOverlappingAll, isAdjacent, eCompare, eIsInteger, eNegativeOf, eLongDivide, exponent, bitLength } from '../../src/index.js'; const sign = Math.sign; const MSI = Number.MAX_SAFE_INTEGER; // 9007199254740991 const MSI_min63 = Number.MAX_SAFE_INTEGER - 63; // 9007199254740928 const MSI_2_53 = MSI*2**53; // 81129638414606672688589750403072 const MSI_plus1 = MSI + 1; // 9007199254740992 const MSI_min1 = MSI - 1; // 9007199254740990 const e1 = [MSI]; // [9007199254740991] const e2 = [2*MSI]; // [18014398509481982] const e3 = [-1,2*MSI]; // [-1,18014398509481982] const e4 = [+1,2*MSI]; // [+1,18014398509481982] const e5 = eSum([[63],[MSI_min63],[MSI_2_53]]); const e6 = eSum([[62],[MSI_min63],[-MSI_2_53]]); const e7 = eSum([[3009], [9]]); const e8 = eSum([[3009], [2]]); const e9 = eSum([[MSI_2_53],[0]]); const ea = eSum([[MSI_2_53],[-1]]); const eb = eSum([[MSI_2_53],[+1]]); const N1 = [4220107938567023, 8.795405735663742e+30, 2.666668833599244e+47]; const D1 = [604814597353253, 2.941662261791943e+31]; const N2 = [ 1511714056433609, 1.9588659696103412e+31, 4.121622845731378e+46, 2.2078201987714595e+63, 2.500962259235055e+79, 2.6404956320519508e+95, 1.8029971214264133e+111, 4.10694639038906e+125, 1.3483846944127788e+143 ]; const D2 = [ 37174531114061, 8.95616194410289e+30, 1.1879369517265606e+46, 9.112820412592545e+61, 5.503733476158258e+78 ]; describe('eLongDivide', function() { it('should correctly do long division, returning the correct quotient and remainder of some Shewchuk expansions', function() { testLongDivide(e7, [10]); testLongDivide(e1, [MSI]); testLongDivide(e1, [MSI_plus1]); testLongDivide(e1, [MSI_min1]); testLongDivide(e1, [2*MSI]); testLongDivide(e2, [MSI]); testLongDivide(e2, [2*MSI]); testLongDivide(e3, [MSI]); testLongDivide(e4, [MSI]); testLongDivide(e5, [MSI]); testLongDivide(e6, [MSI]); testLongDivide([81064793292668910], [93]); testLongDivide([4],[2]); testLongDivide([4],[3]); testLongDivide([1],[3]); testLongDivide([MSI],e5); testLongDivide([MSI_2_53],e9); testLongDivide([MSI_2_53],ea); testLongDivide([MSI_2_53],eb); testLongDivide(N1,D1); testLongDivide(N2,D2); const count = 1000; for (let i=0; i= 0) { console.log('test 2 fails: |remainder| >= |divisor|') return '' + `test 2 fails: |remainder| >= |divisor| N: ${N} N_: ${N_} D: ${D} div: ${div} rem: ${rem} `; } /////////////////////////////////////////////////// // TEST 3 /////////////////////////////////////////////////// // `/` and `%` signs must follow bigint conventions: // // `/`: expect `sign(div) === sign(n) * sign(d)`, e.g. // // console.log(' 7n / 3n = 2n'); // console.log('-7n / 3n = -2n'); // console.log(' 7n / -3n = -2n'); // console.log('-7n / -3n = 2n'); // // `%`: expect `sign(rem) === sign(n)`, e.g. // // console.log(' 7n % 3n = 1'); // console.log('-7n % 3n = -1'); // console.log(' 7n % -3n = 1'); // console.log('-7n % -3n = -1'); /////////////////////////////////////////////////// let signN = sign(N[N.length-1]); let signD = sign(D[D.length-1]); let signDiv = sign(div[div.length-1]); let signRem = sign(rem[rem.length-1]); if (signDiv !== 0) { if (signDiv !== signN * signD) { return '' + `test 3 fails: sign(div) !== sign(n) * sign(d) N: ${N} N_: ${N_} D: ${D} div: ${div} rem: ${rem} `; } } if (signRem !== 0) { if (signRem !== signN) { return '' + `test 3 fails: sign(rem) !== sign(n) N: ${N} N_: ${N_} D: ${D} div: ${div} rem: ${rem} `; } } // TEST 4???? return true; } function getRandomNumber() { let num = Math.round(Math.random() * 10) + 1; let n = scaleFloatsToInts([...Array(num).keys()] .map((c,i) => Math.random() * 2**(i*53))); return n; } /** * * @param as * @returns */ function scaleFloatsToInts(as: number[]) { let e = -1024; for (let i=0; i e) { e = scaleFactor; } } return as.map(a => a*2**e); }