Skip to content

Commit a370bac

Browse files
Finish implementation of stringify.
1 parent c45d44a commit a370bac

10 files changed

+152
-35
lines changed

package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@
2727
"bugs": {
2828
"url": "https://github.com/aureooms/js-rational/issues"
2929
},
30-
"dependencies": {},
30+
"dependencies": {
31+
"@aureooms/js-itertools": "^4.0.0"
32+
},
3133
"devDependencies": {
3234
"@aureooms/js-integer": "6.0.0",
35+
"@aureooms/js-number": "^3.1.0",
36+
"@aureooms/js-prime": "^4.0.0",
3337
"@babel/cli": "7.8.4",
3438
"@babel/core": "7.9.6",
3539
"@babel/polyfill": "7.8.7",

src/_stringify_digits.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export function _stringify_digits ( str , base , { sign , left , transient , repetend } ) {
2+
3+
const toStr = x => str(x, base);
4+
5+
let repr = '' ;
6+
7+
if (sign < 0) repr += '-' ;
8+
9+
repr += toStr(left) ;
10+
11+
if (transient.length || repetend.length) repr += '.' ;
12+
repr += transient.map(toStr).join('') ;
13+
14+
if (repetend.length) repr += '|' ;
15+
repr += repetend.map(toStr).join('') ;
16+
17+
return repr ;
18+
19+
}

src/decimals.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
export function _decimals ( { b , eq , muln , divmod } ) {
66

7-
return function* ( d , n , x ) {
7+
return function* ( d , n , hasrepetend , x ) {
88

99
// Computes the length of the repetend of x/d (1 <= x < d) in base b
1010
// with transient part of size n.
@@ -18,7 +18,9 @@ export function _decimals ( { b , eq , muln , divmod } ) {
1818

1919
}
2020

21-
first = x ;
21+
if ( !hasrepetend ) return ;
22+
23+
const first = x ;
2224

2325
x = muln(x, b) ;
2426
const [q, r] = divmod(x, d) ;

src/digits.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { take } from '@aureooms/js-itertools' ;
2+
import { _decimals } from './decimals' ;
3+
import { _transient } from './transient' ;
4+
5+
export function _digits ( { b , bfactors , jz , gt1 , eq , muln , divmodn , divmod , egcd , sgn , abs } ) {
6+
7+
const tr = _transient( { bfactors , jz , gt1 , divmodn } ) ;
8+
const dec = _decimals( { b , eq , muln , divmod } ) ;
9+
10+
return function ( x , d ) {
11+
12+
const [ left , r ] = divmod(abs(x), d) ;
13+
14+
const { u , v } = egcd(d, r) ;
15+
16+
const [ transient_length , has_repetend ] = tr( v ) ;
17+
18+
const decimals = dec(v, transient_length, has_repetend , u) ;
19+
20+
const transient = [ ...take(decimals, transient_length) ] ;
21+
22+
const repetend = [ ...decimals ] ;
23+
24+
return { sign: sgn(x) , left , transient , repetend } ;
25+
26+
}
27+
28+
}

src/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ export * from './pow' ;
66
export * from './cmp' ;
77
export * from './cmp_no_bounds' ;
88
export * from './simplify' ;
9+
export * from './digits' ;
10+
export * from './_stringify_digits' ;

src/stringify.js

-23
This file was deleted.

src/transient.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export function _transient ( { bfactors , jz , gt1 , divmodn } ) {
2222

2323
if (!jz(r)) break ;
2424

25-
++mm ;
25+
++m ;
2626
d = q ;
2727

2828
}

test/src/_fixtures.js

+27-3
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,47 @@ export const ALU = [
88
add : (a, b) => a.add(b),
99
sub : (a, b) => a.sub(b),
1010
mul : (a, b) => a.mul(b),
11+
muln : (a, b) => a.mul(b),
1112
div : (a, b) => a.div(b),
1213
reg : x => int(x),
1314
str : x => x.toString(),
1415
jz : x => x.eq(0),
1516
lt0 : x => x.lt(0),
17+
gt1 : x => x.gt(1),
1618
cmp : (a,b) => a.cmp(b),
19+
eq : (a,b) => a.eq(b),
1720
neg : x => x.neg(),
1821
sgn : x => x.cmp(0),
22+
abs : x => x.abs(),
1923
divmod : (a,b) => [a.div(b), a.mod(b)],
24+
divmodn : (a,b) => [a.div(b), a.mod(b)],
2025
pown : (x,n) => x.pow(n),
2126
},
2227
{
2328
name : 'bn.js',
2429
add : (a, b) => a.add(b),
2530
sub : (a, b) => a.sub(b),
2631
mul : (a, b) => a.mul(b),
32+
muln : (a, b) => a.muln(b),
2733
div : (a, b) => a.div(b),
2834
reg : x => new BN(x),
29-
str : x => x.toString(),
35+
str : (x, base) => x.toString(base),
3036
jz : x => x.eqn(0),
3137
lt0 : x => x.ltn(0),
38+
gt1 : x => x.gtn(1),
3239
cmp : (a,b) => a.cmp(b),
40+
eq : (a,b) => a.eq(b),
3341
sgn : x => x.cmpn(0),
42+
abs : x => x.abs(),
3443
neg : x => x.neg(),
3544
divmod : (a,b) => {
3645
const { div , mod } = a.divmod(b) ;
3746
return [div, mod] ;
3847
} ,
48+
divmodn : (a,b) => {
49+
const { div , mod } = a.divmod(new BN(b)) ;
50+
return [div, mod] ;
51+
} ,
3952
egcd : (a,b) => {
4053
const gcd = a.gcd(b) ;
4154
return { u: b.div(gcd), v: a.div(gcd) } ;
@@ -47,16 +60,27 @@ export const ALU = [
4760
add : (a, b) => a.add(b),
4861
sub : (a, b) => a.sub(b),
4962
mul : (a, b) => a.mul(b),
63+
muln : (a, b) => a.muln(b),
5064
div : (a, b) => a.div(b),
5165
reg : x => ZZ.from(x),
52-
str : x => x.toString(),
66+
str : (x, base) => x.toString(base),
5367
jz : x => x.iszero(),
5468
lt0 : x => x.sign() < 0,
69+
gt1 : x => x.gtn(1),
5570
cmp : (a,b) => a.cmp(b),
71+
eq : (a,b) => a.eq(b),
5672
sgn : x => x.sign(),
73+
abs : x => x.abs(),
5774
neg : x => x.opposite(),
5875
divmod : (a,b) => a.divmod(b),
59-
egcd : (a,b) => a.egcd(b),
76+
divmodn : (a,b) => a.divmodn(b),
77+
egcd : (a,b) => {
78+
const { u , v } = a.egcd(b) ;
79+
return {
80+
u: u.iabs(),
81+
v: v.iabs(),
82+
} ;
83+
},
6084
pown : (x,n) => x.pown(n),
6185
}
6286
];

test/src/core.js

+41-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
import test from 'ava';
2-
import { _add , _sub , _mul , _div , _pow , _cmp , _cmp_no_bounds , _simplify } from '../../src';
2+
import { __factorize__ } from '@aureooms/js-prime' ;
3+
import { $2, iadd1, eq0, gt1, divmod } from "@aureooms/js-number" ;
4+
import {
5+
_add , _sub , _mul , _div , _pow ,
6+
_cmp , _cmp_no_bounds ,
7+
_simplify , _digits , _stringify_digits
8+
} from '../../src';
39

410
const GOOGOL = '10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ;
511

12+
const factorize = __factorize__( $2, iadd1, eq0, gt1, divmod ) ;
13+
14+
const ufactors = n => new Set(factorize(n)) ;
15+
616
import { ALU } from './_fixtures' ;
717

818
function binary ( t , alu , [ [ _x , _y , factory ] , a , b , c , d , e ] ) {
@@ -51,14 +61,12 @@ function unary ( t , alu , [ [ _x , _y , factory ] , a , b , e ] ) {
5161

5262
const apply = factory( alu );
5363

54-
const repr = x => `${alu.str(x[0])}/${alu.str(x[1])}` ;
55-
5664
const _a = alu.reg(a);
5765
const _b = alu.reg(b);
5866

5967
const z = apply( _a , _b ) ;
6068

61-
t.is(e, repr(z));
69+
t.is(e, z);
6270

6371
}
6472

@@ -72,7 +80,22 @@ const mul = [ 'mul' , '*' , [ _mul ] , binary ] ;
7280
const div = [ 'div' , '/' , [ _div ] , binary ] ;
7381
const pow = [ 'pow' , '^' , [ _pow ] , binary_n ] ;
7482
const cmp = [ 'cmp' , '~' , [ _cmp , _cmp_no_bounds ] , binary ] ;
75-
const simplify = [ 'simplify' , '=' , [ _simplify ] , unary , alu => alu.egcd ] ;
83+
const simplify = [ 'simplify' , '=' , [
84+
alu => {
85+
const repr = x => `${alu.str(x[0])}/${alu.str(x[1])}` ;
86+
const simp = _simplify(alu) ;
87+
return (a,b) => repr(simp(a,b)) ;
88+
}
89+
] , unary , alu => alu.egcd ] ;
90+
91+
const stringify = [ 'stringify' , '=' , [
92+
alu => {
93+
const b = 10 ;
94+
const bfactors = ufactors( b ) ;
95+
const digits = _digits({ b , bfactors , ...alu }) ;
96+
return ( x , d ) => _stringify_digits( alu.str , b , digits(x, d) ) ;
97+
}
98+
] , unary , alu => alu.egcd ] ;
7699

77100
const PARAMS = [
78101

@@ -166,6 +189,19 @@ const PARAMS = [
166189
[ simplify , '-170141183460469231731687303715884105729' , '3' , '-56713727820156410577229101238628035243/1' ] ,
167190
[ simplify , '-3' , '170141183460469231731687303715884105729' , '-1/56713727820156410577229101238628035243' ] ,
168191

192+
[ stringify , '1' , '7' , '0.|142857' ] ,
193+
[ stringify , '-4' , '8' , '-0.5' ] ,
194+
[ stringify , '7' , '14' , '0.5' ] ,
195+
[ stringify , '0' , '43' , '0' ] ,
196+
[ stringify , '86' , '43' , '2' ] ,
197+
[ stringify , '2' , '46' , '0.|0434782608695652173913' ] ,
198+
[ stringify , '1' , '46' , '0.0|2173913043478260869565' ] ,
199+
[ stringify , '1' , '14' , '0.0|714285'] ,
200+
[ stringify , '1' , '45' , '0.0|2' ] ,
201+
[ stringify , '22' , '7' , '3.|142857' ] ,
202+
[ stringify , '355' , '113' , '3.|1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168' ] ,
203+
[ stringify , '7775' , '2260' , '3.44|0265486725663716814159292035398230088495575221238938053097345132743362831858407079646017699115044247787610619469' ] ,
204+
169205
] ;
170206

171207
for (const alu of ALU)

yarn.lock

+25
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
# yarn lockfile v1
33

44

5+
"@aureooms/js-collections-deque@^4.0.0":
6+
version "4.0.0"
7+
resolved "https://registry.yarnpkg.com/@aureooms/js-collections-deque/-/js-collections-deque-4.0.0.tgz#cb6ff3070f4413023622db817da261f91e42aef0"
8+
integrity sha512-+dI0PSkshl0vKmeyfzWM5Xtfopu4XYIrlqKKq3emjyuCi1DCO9SaPIgKblMDjl9WttmJhTYsunNyPYula5woAw==
9+
dependencies:
10+
"@aureooms/js-error" "^4.0.0"
11+
512
"@aureooms/js-error@^4.0.0":
613
version "4.0.0"
714
resolved "https://registry.yarnpkg.com/@aureooms/js-error/-/js-error-4.0.0.tgz#cea0a145f5290f443911b3d1890d7254a18eeb9b"
@@ -20,6 +27,24 @@
2027
"@aureooms/js-error" "^4.0.0"
2128
"@aureooms/js-integer-big-endian" "^8.0.0"
2229

30+
"@aureooms/js-itertools@^4.0.0":
31+
version "4.0.0"
32+
resolved "https://registry.yarnpkg.com/@aureooms/js-itertools/-/js-itertools-4.0.0.tgz#2f7247b4a89202606bb54a731753590625b4b185"
33+
integrity sha512-QhCT+RDUbWPL7h3RA7LcXdC1IQdR3Bfl0Re0ClDxem7DUnRbHuL4Nlwgo3UoqaRBE8OI4RpBw+hXVVqVg14J9Q==
34+
dependencies:
35+
"@aureooms/js-collections-deque" "^4.0.0"
36+
"@aureooms/js-error" "^4.0.0"
37+
38+
"@aureooms/js-number@^3.1.0":
39+
version "3.1.0"
40+
resolved "https://registry.yarnpkg.com/@aureooms/js-number/-/js-number-3.1.0.tgz#460155de73084d25e648680309d9d1d941e3df89"
41+
integrity sha512-Z+Dmml9TjuhnxaOIWu8OZ3iYFPJsLJNynv1qgwYTO7dsZznMPge1ME5VmFeTNNsZSg9DtavXVyfYla+XxWXHRg==
42+
43+
"@aureooms/js-prime@^4.0.0":
44+
version "4.0.0"
45+
resolved "https://registry.yarnpkg.com/@aureooms/js-prime/-/js-prime-4.0.0.tgz#95ceb59a67ca009afb76b3045daab174b40f24f2"
46+
integrity sha512-U5Hji39rqTK+ktMTQZvSx/AhX09wLj3ESQPl7fep/ip/FMskeaHtCK8zAQ6QcneLDBCHOMV0x6C9CckWqiCzag==
47+
2348
2449
version "7.8.4"
2550
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.8.4.tgz#505fb053721a98777b2b175323ea4f090b7d3c1c"

0 commit comments

Comments
 (0)