-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcarryless_tests.js
171 lines (146 loc) · 5.37 KB
/
carryless_tests.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// @flow
/* eslint-env jasmine */
/* eslint no-bitwise: off */
'use strict';
/* ::
import {
carrylessAdd32,
carrylessAddBig,
carrylessMul32,
carrylessMulBig,
carrylessDiv32,
carrylessDivBig,
} from './carryless';
*/
/*
global
BigInteger,
carrylessAdd32,
carrylessAddBig,
carrylessMul32,
carrylessMulBig,
carrylessDiv32,
carrylessDivBig,
*/
describe('carryless', () => {
it('add32', () => {
expect(carrylessAdd32(1, 1)).toBe(0);
expect(carrylessAdd32(1, 2)).toBe(3);
expect(carrylessAdd32(2, 1)).toBe(3);
expect(carrylessAdd32(2, 2)).toBe(0);
expect(carrylessAdd32(0xffffffff, 0)).toBe(0xffffffff);
expect(carrylessAdd32(-1, 0)).toBe(0xffffffff);
});
const toBigInt = (
n /* : number | string */,
base /* : number */ = 10
) /* : BigInteger */ =>
new BigInteger(typeof n === 'number' ? n.toString(base) : n, base);
const carrylessAddBigStr = (
a /* : number | string */,
b /* : number | string */,
base /* : number */ = 10
) /* : string */ =>
carrylessAddBig(toBigInt(a, base), toBigInt(b, base)).toString(base);
it('addBig', () => {
expect(carrylessAddBigStr(1, 1)).toBe('0');
expect(carrylessAddBigStr(1, 2)).toBe('3');
expect(carrylessAddBigStr(2, 1)).toBe('3');
expect(carrylessAddBigStr(2, 2)).toBe('0');
expect(carrylessAddBigStr(0xffffffff, 0, 16)).toBe('ffffffff');
expect(carrylessAddBigStr('ffffffffff', 1, 16)).toBe('fffffffffe');
});
it('mul32', () => {
expect(carrylessMul32(7, 0)).toBe(0);
expect(carrylessMul32(7, 1)).toBe(7);
expect(carrylessMul32(7, 2)).toBe(14);
expect(carrylessMul32(7, 3)).toBe(9);
expect(carrylessMul32(7, 4)).toBe(28);
expect(carrylessMul32(7, 5)).toBe(27);
expect(carrylessMul32(0, 7)).toBe(0);
expect(carrylessMul32(1, 7)).toBe(7);
expect(carrylessMul32(2, 7)).toBe(14);
expect(carrylessMul32(3, 7)).toBe(9);
expect(carrylessMul32(4, 7)).toBe(28);
expect(carrylessMul32(5, 7)).toBe(27);
expect(carrylessMul32(1 << 31, 1)).toBe(0x80000000);
expect(carrylessMul32(1, 1 << 31)).toBe(0x80000000);
expect(carrylessMul32(1 << 31, 2)).toBe(0);
expect(carrylessMul32(2, 1 << 31)).toBe(0);
});
const carrylessMulBigStr = (
a /* : number | string */,
b /* : number | string */,
base /* : number */ = 10
) /* : string */ =>
carrylessMulBig(toBigInt(a, base), toBigInt(b, base)).toString(base);
it('mulBig', () => {
expect(carrylessMulBigStr(7, 0)).toEqual('0');
expect(carrylessMulBigStr(7, 1)).toEqual('7');
expect(carrylessMulBigStr(7, 2)).toEqual('14');
expect(carrylessMulBigStr(7, 3)).toEqual('9');
expect(carrylessMulBigStr(7, 4)).toEqual('28');
expect(carrylessMulBigStr(7, 5)).toEqual('27');
expect(carrylessMulBigStr(0, 7)).toEqual('0');
expect(carrylessMulBigStr(1, 7)).toEqual('7');
expect(carrylessMulBigStr(2, 7)).toEqual('14');
expect(carrylessMulBigStr(3, 7)).toEqual('9');
expect(carrylessMulBigStr(4, 7)).toEqual('28');
expect(carrylessMulBigStr(5, 7)).toEqual('27');
expect(carrylessMulBigStr(0x80000000, 1, 16)).toEqual('80000000');
expect(carrylessMulBigStr(1, 0x80000000, 16)).toEqual('80000000');
expect(carrylessMulBigStr(0x80000000, 2, 16)).toEqual('100000000');
expect(carrylessMulBigStr(2, 0x80000000, 16)).toEqual('100000000');
expect(carrylessMulBigStr(0x80000000, 0x80000000, 16)).toEqual(
'4000000000000000'
);
});
it('div32', () => {
expect(carrylessDiv32(4, 1)).toEqual({ q: 4, r: 0 });
expect(carrylessDiv32(4, 2)).toEqual({ q: 2, r: 0 });
expect(carrylessDiv32(4, 3)).toEqual({ q: 3, r: 1 });
expect(carrylessDiv32(4, 4)).toEqual({ q: 1, r: 0 });
expect(carrylessDiv32(7, 1)).toEqual({ q: 7, r: 0 });
expect(carrylessDiv32(7, 2)).toEqual({ q: 3, r: 1 });
expect(carrylessDiv32(7, 3)).toEqual({ q: 2, r: 1 });
expect(carrylessDiv32(7, 4)).toEqual({ q: 1, r: 3 });
expect(carrylessDiv32(7, 5)).toEqual({ q: 1, r: 2 });
expect(carrylessDiv32(0xffffffff, 1)).toEqual({ q: 0xffffffff, r: 0 });
expect(carrylessDiv32(0xffffffff, 2)).toEqual({ q: 0x7fffffff, r: 1 });
expect(carrylessDiv32(0xf0000000, 0xffffffff)).toEqual({
q: 1,
r: 0xfffffff,
});
});
const carrylessDivBigStr = (
a /* : number | string */,
b /* : number | string */,
base /* : number */ = 10
) => {
const { q, r } = carrylessDivBig(toBigInt(a, base), toBigInt(b, base));
return { q: q.toString(base), r: r.toString(base) };
};
it('divBig', () => {
expect(carrylessDivBigStr(4, 1)).toEqual({ q: '4', r: '0' });
expect(carrylessDivBigStr(4, 2)).toEqual({ q: '2', r: '0' });
expect(carrylessDivBigStr(4, 3)).toEqual({ q: '3', r: '1' });
expect(carrylessDivBigStr(4, 4)).toEqual({ q: '1', r: '0' });
expect(carrylessDivBigStr(7, 1)).toEqual({ q: '7', r: '0' });
expect(carrylessDivBigStr(7, 2)).toEqual({ q: '3', r: '1' });
expect(carrylessDivBigStr(7, 3)).toEqual({ q: '2', r: '1' });
expect(carrylessDivBigStr(7, 4)).toEqual({ q: '1', r: '3' });
expect(carrylessDivBigStr(7, 5)).toEqual({ q: '1', r: '2' });
expect(carrylessDivBigStr(0xffffffff, 1, 16)).toEqual({
q: 'ffffffff',
r: '0',
});
expect(carrylessDivBigStr(0xffffffff, 2, 16)).toEqual({
q: '7fffffff',
r: '1',
});
expect(carrylessDivBigStr(0xf0000000, 0xffffffff, 16)).toEqual({
q: '1',
r: 'fffffff',
});
});
});