Skip to content

Commit d218211

Browse files
✨ feat: Add parsing methods.
1 parent 4864223 commit d218211

File tree

7 files changed

+108
-5
lines changed

7 files changed

+108
-5
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
},
3333
"devDependencies": {
3434
"@aureooms/js-integer": "6.0.0",
35+
"@aureooms/js-integer-big-endian": "^8.0.0",
3536
"@aureooms/js-number": "3.1.0",
3637
"@aureooms/js-prime": "4.0.0",
3738
"@babel/cli": "7.8.4",

src/_constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
export const DECIMAL_PREFIX = '.' ;
3+
export const REPETEND_PREFIX = '|' ;
4+
export const FRACTION_SEP = '/' ;

src/_parse_fixed_point.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
import { DECIMAL_PREFIX , REPETEND_PREFIX } from './_constants' ;
3+
4+
export function _parse_fixed_point ( { _chr , reg , sub } ) {
5+
6+
return function ( base , s ) {
7+
8+
const [ integral , decimal ] = s.split(DECIMAL_PREFIX) ;
9+
const [ transient , repetend ] = decimal.split(REPETEND_PREFIX) ;
10+
11+
const _integral = integral === '0' ? '' : integral ;
12+
const _repetend = repetend || '' ;
13+
14+
const _denominator = ( !_repetend ?
15+
_chr(1) :
16+
(new Array(repetend.length+1)).join( _chr(base-1) )
17+
) +
18+
(new Array(transient.length+1)).join( _chr(0) ) ;
19+
20+
const _big = _integral + transient + _repetend ;
21+
const _small = _integral + transient ;
22+
23+
const _bign = reg(_big, base) ;
24+
const _smalln = reg(_small, base) ;
25+
26+
const numerator = _repetend ? sub(_bign, _smalln) : _smalln ;
27+
const denominator = reg(_denominator, base) ;
28+
29+
return [ numerator , denominator ] ;
30+
31+
}
32+
33+
}

src/_parse_fraction.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
import { FRACTION_SEP } from './_constants' ;
3+
4+
export function _parse_fraction ( { reg } ) {
5+
6+
return function ( base , s ) {
7+
8+
const [ _numerator , _denominator ] = s.split(FRACTION_SEP) ;
9+
10+
return [ reg(_numerator, base), reg(_denominator, base) ] ;
11+
12+
}
13+
14+
}

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ export * from './cmp_no_bounds' ;
88
export * from './simplify' ;
99
export * from './digits' ;
1010
export * from './_stringify_digits' ;
11+
export * from './_parse_fixed_point' ;
12+
export * from './_parse_fraction' ;

test/src/_fixtures.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import int from 'int' ;
22
import BN from 'bn.js' ;
33
import { ZZ } from '@aureooms/js-integer' ;
4+
import { _chr } from '@aureooms/js-integer-big-endian' ;
45

56
export const ALU = [
67
{
78
name : 'int',
9+
anybase: false,
810
add : (a, b) => a.add(b),
911
sub : (a, b) => a.sub(b),
1012
mul : (a, b) => a.mul(b),
@@ -23,15 +25,17 @@ export const ALU = [
2325
divmod : (a,b) => [a.div(b), a.mod(b)],
2426
divmodn : (a,b) => [a.div(b), a.mod(b)],
2527
pown : (x,n) => x.pow(n),
28+
_chr,
2629
},
2730
{
2831
name : 'bn.js',
32+
anybase: true,
2933
add : (a, b) => a.add(b),
3034
sub : (a, b) => a.sub(b),
3135
mul : (a, b) => a.mul(b),
3236
muln : (a, b) => a.muln(b),
3337
div : (a, b) => a.div(b),
34-
reg : x => new BN(x),
38+
reg : (x, base) => new BN(x, base),
3539
str : (x, base) => x.toString(base),
3640
jz : x => x.eqn(0),
3741
lt0 : x => x.ltn(0),
@@ -54,15 +58,17 @@ export const ALU = [
5458
return { u: b.div(gcd), v: a.div(gcd) } ;
5559
} ,
5660
pown : (x,n) => x.pow(new BN(n)),
61+
_chr,
5762
},
5863
{
5964
name : '@aureooms/js-integer',
65+
anybase: true,
6066
add : (a, b) => a.add(b),
6167
sub : (a, b) => a.sub(b),
6268
mul : (a, b) => a.mul(b),
6369
muln : (a, b) => a.muln(b),
6470
div : (a, b) => a.div(b),
65-
reg : x => ZZ.from(x),
71+
reg : (x, base) => ZZ.from(x, base),
6672
str : (x, base) => x.toString(base),
6773
jz : x => x.iszero(),
6874
lt0 : x => x.sign() < 0,
@@ -82,6 +88,7 @@ export const ALU = [
8288
} ;
8389
},
8490
pown : (x,n) => x.pown(n),
91+
_chr,
8592
}
8693
];
8794

test/src/core.js

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { $2, iadd1, eq0, gt1, divmod } from "@aureooms/js-number" ;
44
import {
55
_add , _sub , _mul , _div , _pow ,
66
_cmp , _cmp_no_bounds ,
7-
_simplify , _digits , _stringify_digits
7+
_simplify , _digits , _stringify_digits ,
8+
_parse_fraction , _parse_fixed_point
89
} from '../../src';
910

1011
const GOOGOL = '10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ;
@@ -70,8 +71,22 @@ function unary ( t , alu , [ [ _x , _y , factory ] , a , b , e ] ) {
7071

7172
}
7273

73-
unary.title = ( _ , alu , [ [ name , impl ] , a , b , e ] ) => {
74-
return `${name}<${impl.name}, ${alu.name}> ${name}(${a}/${b}) = ${e}` ;
74+
unary.title = ( _ , alu , [ [ name , op , impl ] , a , b , e ] ) => {
75+
return `${name}<${impl.name}, ${alu.name}> ${name}(${a}/${b}) ${op} ${e}` ;
76+
} ;
77+
78+
function macro_parse ( t , alu , [ [ _x , _y , factory ] , base , s , e ] ) {
79+
80+
const apply = factory( alu );
81+
82+
const z = apply(base, s)
83+
84+
t.is(e, z) ;
85+
86+
}
87+
88+
macro_parse.title = ( _ , alu , [ [ name , op , impl ] , base , s , e ] ) => {
89+
return `${name}<${impl.name}, ${alu.name}> ${name}(${base},${s}) ${op} ${e}` ;
7590
} ;
7691

7792
const add = [ 'add' , '+' , [ _add ] , binary ] ;
@@ -95,10 +110,28 @@ const stringify_n = b => alu => {
95110
return ( x , d ) => _stringify_digits( alu.str , b , digits(x, d) ) ;
96111
} ;
97112

113+
98114
const stringify_10 = [ 'stringify_10' , '=' , [ stringify_n(10) ] , unary , alu => alu.egcd ] ;
99115
const stringify_2 = [ 'stringify_2' , '=' , [ stringify_n(2) ] , unary , alu => alu.egcd ] ;
100116
const stringify_19 = [ 'stringify_19' , '=' , [ stringify_n(19) ] , unary , alu => alu.egcd ] ;
101117

118+
const parse_fraction = [ 'parse_fraction' , '=' , [
119+
alu => {
120+
const repr = x => `${alu.str(x[0])}/${alu.str(x[1])}` ;
121+
const simp = _simplify(alu) ;
122+
const parse = _parse_fraction(alu);
123+
return (base, s) => repr(simp(...parse(base, s))) ;
124+
}
125+
] , macro_parse , alu => alu.anybase ] ;
126+
const parse_fixed_point = [ 'parse_fixed_point' , '=' , [
127+
alu => {
128+
const repr = x => `${alu.str(x[0])}/${alu.str(x[1])}` ;
129+
const simp = _simplify(alu) ;
130+
const parse = _parse_fixed_point(alu);
131+
return (base, s) => repr(simp(...parse(base, s))) ;
132+
}
133+
] , macro_parse , alu => alu.egcd && alu.anybase ] ;
134+
102135
const PARAMS = [
103136

104137
[ add , '3', '4', '1', '4', 1] ,
@@ -214,6 +247,15 @@ const PARAMS = [
214247

215248
[ stringify_19 , '14' , '13', '1.|18ebd2ha475g'] , // HOHO
216249

250+
[ parse_fraction , 10 , '1/2' , '1/2' ] ,
251+
[ parse_fraction , 10 , '10/20' , '1/2' ] ,
252+
253+
[ parse_fixed_point , 19 , '1.|18ebd2ha475g' , '14/13' ] ,
254+
[ parse_fixed_point , 2 , '0.1' , '1/2' ] ,
255+
[ parse_fixed_point , 10 , '3.|1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168' , '355/113' ] ,
256+
257+
[ parse_fixed_point , 10 , '0.0|2' , '1/45' ] ,
258+
217259
] ;
218260

219261
for (const alu of ALU)

0 commit comments

Comments
 (0)