repeating-decimal 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +22 -0
- package/dist/index.test.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# repeating-decimal
|
|
2
|
+
Convert repeating decimals into exact fractions.
|
|
3
|
+
|
|
4
|
+
This package provides a utility to convert numbers with repeating parts(e.g. 0.987123123123...=41089/41625) into a reduced fractional representation.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- Convert repeating decimals to fractions
|
|
9
|
+
- Supports arbitrary bases (2–36)
|
|
10
|
+
- Fully written in TypeScript
|
|
11
|
+
- ESM-compatible
|
|
12
|
+
- No external runtime dependencies
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install repeating-fraction
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
```typescript
|
|
22
|
+
import { make_fraction } from "repeating-fraction";
|
|
23
|
+
|
|
24
|
+
const result = make_fraction("009","123",10));
|
|
25
|
+
|
|
26
|
+
console.log(result);
|
|
27
|
+
// {numerator: 1519,denominator: 166500}
|
|
28
|
+
// 1519/166500=0.009123123...
|
|
29
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA4EA,MAAM,WAAW,QAAQ;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,GAAE,QAAQ,CA+B1E"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
function gcd(m, n) {
|
|
2
|
+
if (m < n)
|
|
3
|
+
return gcd(n, m);
|
|
4
|
+
var r = m % n;
|
|
5
|
+
if (r == 0)
|
|
6
|
+
return n;
|
|
7
|
+
return gcd(n, r);
|
|
8
|
+
}
|
|
9
|
+
function lcm(a, b) {
|
|
10
|
+
return a * b / gcd(a, b);
|
|
11
|
+
}
|
|
12
|
+
function isNaN_array(array) {
|
|
13
|
+
return array.filter((v) => { return Number.isNaN(v); }).length > 0;
|
|
14
|
+
}
|
|
15
|
+
//return a,b=1固定
|
|
16
|
+
// a/b
|
|
17
|
+
function make_fraction_body(body, base) {
|
|
18
|
+
body = body.reverse();
|
|
19
|
+
let a_up = 0;
|
|
20
|
+
for (const [i, v] of body.entries()) {
|
|
21
|
+
a_up += Math.pow(base, i) * v;
|
|
22
|
+
}
|
|
23
|
+
let a_down = Math.pow(base, body.length) - 1;
|
|
24
|
+
let a_temp1 = gcd(a_up, a_down);
|
|
25
|
+
a_up /= a_temp1;
|
|
26
|
+
a_down /= a_temp1;
|
|
27
|
+
return [a_up, a_down];
|
|
28
|
+
}
|
|
29
|
+
//ヘッダー部
|
|
30
|
+
function make_fraction_head(head, base) {
|
|
31
|
+
head = head.reverse();
|
|
32
|
+
let a_up = 0;
|
|
33
|
+
for (const [i, v] of head.entries()) {
|
|
34
|
+
a_up += v * Math.pow(base, i);
|
|
35
|
+
}
|
|
36
|
+
if (a_up == 0) {
|
|
37
|
+
return [0, 0];
|
|
38
|
+
}
|
|
39
|
+
let a_down = Math.pow(base, head.length);
|
|
40
|
+
let a_temp1 = gcd(a_up, a_down);
|
|
41
|
+
a_up /= a_temp1;
|
|
42
|
+
a_down /= a_temp1;
|
|
43
|
+
return [a_up, a_down];
|
|
44
|
+
}
|
|
45
|
+
function assertValidDigits(array, name) {
|
|
46
|
+
if (isNaN_array(array)) {
|
|
47
|
+
throw new Error(`${name}は指定した進数の数値を入力してください。`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function check_parameter(head, body, base) {
|
|
51
|
+
if (!(2 <= base && base <= 36)) {
|
|
52
|
+
throw new Error("進数は2から36まで指定可能です。");
|
|
53
|
+
}
|
|
54
|
+
const pattern = /^[0-9a-zA-Z]+$/;
|
|
55
|
+
if (!pattern.test(head)) {
|
|
56
|
+
throw new Error("headは英数値しか入力出来ません。");
|
|
57
|
+
}
|
|
58
|
+
if (!pattern.test(body)) {
|
|
59
|
+
throw new Error("bodyは英数値しか入力出来ません。");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function make_fraction(head, body, base) {
|
|
63
|
+
check_parameter(head, body, base);
|
|
64
|
+
const head_array = head.split('').map(v => parseInt(v, base));
|
|
65
|
+
const body_array = body.split('').map(v => parseInt(v, base));
|
|
66
|
+
assertValidDigits(head_array, "head");
|
|
67
|
+
assertValidDigits(body_array, "body");
|
|
68
|
+
let head_result = make_fraction_head(head_array, base);
|
|
69
|
+
let body_result = make_fraction_body(body_array, base);
|
|
70
|
+
body_result[1] *= Math.pow(base, body_array.length);
|
|
71
|
+
let result = [0, 0];
|
|
72
|
+
if (head_result[0] != 0) {
|
|
73
|
+
let result_temp1 = lcm(head_result[1], body_result[1]);
|
|
74
|
+
head_result[0] *= result_temp1 / head_result[1];
|
|
75
|
+
head_result[1] = result_temp1;
|
|
76
|
+
body_result[0] *= result_temp1 / body_result[1];
|
|
77
|
+
body_result[1] = result_temp1;
|
|
78
|
+
result = [(head_result[0] + body_result[0]), head_result[1]];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
result = body_result;
|
|
82
|
+
}
|
|
83
|
+
let result_temp2 = gcd(result[0], result[1]);
|
|
84
|
+
result[0] /= result_temp2;
|
|
85
|
+
result[1] /= result_temp2;
|
|
86
|
+
return {
|
|
87
|
+
numerator: result[0],
|
|
88
|
+
denominator: result[1]
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { test, expect } from "vitest";
|
|
2
|
+
import { make_fraction } from "./index.js";
|
|
3
|
+
test("check make_fraction", () => {
|
|
4
|
+
//41089/41625=0.987123123...
|
|
5
|
+
expect(make_fraction("987", "123", 10)).toStrictEqual({
|
|
6
|
+
numerator: 41089,
|
|
7
|
+
denominator: 41625
|
|
8
|
+
});
|
|
9
|
+
expect(make_fraction("009", "123", 10)).toStrictEqual({
|
|
10
|
+
numerator: 1519,
|
|
11
|
+
denominator: 166500
|
|
12
|
+
});
|
|
13
|
+
expect(make_fraction("987", "01", 10)).toStrictEqual({
|
|
14
|
+
numerator: 97723,
|
|
15
|
+
denominator: 99000,
|
|
16
|
+
});
|
|
17
|
+
expect(make_fraction("0a", "bc", 16)).toStrictEqual({
|
|
18
|
+
numerator: 1369,
|
|
19
|
+
denominator: 32640,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAG,MAAM,EAAC,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,aAAa,EAAC,MAAM,YAAY,CAAC;AAG1C,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE;IAChC,4BAA4B;IAC5B,MAAM,CAAC,aAAa,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACnD,SAAS,EAAC,KAAK;QACf,WAAW,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACnD,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,MAAM;KACnB,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAClD,SAAS,EAAE,KAAK;QAChB,WAAW,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAC,IAAI,EAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACjD,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,KAAK;KAClB,CAAC,CAAC;AAEJ,CAAC,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "repeating-decimal",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Convert repeating decimals into exact fractions",
|
|
5
|
+
"type": "module",
|
|
6
|
+
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"test": "vitest",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
"keywords": [
|
|
27
|
+
"math",
|
|
28
|
+
"fraction",
|
|
29
|
+
"repeating-decimal",
|
|
30
|
+
"typescript"
|
|
31
|
+
],
|
|
32
|
+
|
|
33
|
+
"author": "PenguinCabinet",
|
|
34
|
+
"license": "MIT"
|
|
35
|
+
}
|