Skip to content

Commit da90f27

Browse files
Add BigDecimal Sqrt (#20)
2 parents 6d41517 + 3ba4977 commit da90f27

File tree

6 files changed

+255
-10
lines changed

6 files changed

+255
-10
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jsbi-calculator",
3-
"version": "0.3.4",
3+
"version": "0.3.5",
44
"description": "JSBI-Calculator is a calculator utility to perform arbitrary arithmetic computation, with the help of JSBI-based BigDecimal.",
55
"main": "dist/jsbi-calculator.js",
66
"module": "dist/jsbi-calculator.mjs",

readme.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,13 @@ The following operations are available. Please mind the factors which are
100100
negative must start with "-" and be surrounded by parentheses, e.g. (-11) and
101101
the positive ones can not start with "+".
102102

103-
| Operation | Symbol |
104-
| -------------- | ------ |
105-
| Addition | `+` |
106-
| Subtration | `-` |
107-
| Multiplication | `*` |
108-
| Division | `/` |
103+
| Operation | Symbol |
104+
| -------------- | ----------------------------------- |
105+
| Addition | `+` |
106+
| Subtration | `-` |
107+
| Multiplication | `*` |
108+
| Division | `/` |
109+
| Square | JBC.BigDecimal.sqrt(num).toString() |
109110

110111
## Thanks
111112

src/jsbi-calculator.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,26 @@ class BigDecimal {
142142
new BigDecimal(num)._n
143143
);
144144
}
145+
// Sqrt operation utilizing Newton's method
146+
static sqrt(num: BigDecimal | string): BigDecimal | typeof NaN {
147+
if (new BigDecimal(num).toString() === "0") return new BigDecimal("0");
148+
if (new BigDecimal(num).toString().startsWith("-")) return NaN;
149+
let result = new BigDecimal(num);
150+
let distance: BigDecimal | "0" = "0";
151+
do {
152+
result = new BigDecimal(result)
153+
.add(new BigDecimal(num).divide(new BigDecimal(result)))
154+
.divide(new BigDecimal("2"));
155+
distance = new BigDecimal(result).subtract(
156+
new BigDecimal(
157+
new BigDecimal(result)
158+
.add(new BigDecimal(num).divide(new BigDecimal(result)))
159+
.divide(new BigDecimal("2"))
160+
)
161+
);
162+
} while (Math.abs(Number(distance.toString())) > 1e-18);
163+
return result;
164+
}
145165
toString(): string {
146166
// issue #15:
147167
// jsbi - calculator not working
@@ -446,6 +466,7 @@ const JBC = {
446466
arrayizeExpression,
447467
jsbiCal,
448468
rpnParse,
469+
BigDecimal,
449470
};
450471

451472
export default JBC;

test/test.html

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
const { assert, expect } = chai;
2727
// JBC from jsbi-calculator-umd
28-
const { calculator, arrayizeExpression, rpnParse, jsbiCal } = JBC;
28+
const { calculator, arrayizeExpression, rpnParse, jsbiCal, BigDecimal } =
29+
JBC;
2930

3031
let expression;
3132

@@ -26264,6 +26265,80 @@
2626426265
expect(result).to.be.a("string");
2626526266
expect(result).to.equal("0");
2626626267

26268+
let squareNumber, root;
26269+
26270+
squareNumber = "0";
26271+
root = BigDecimal.sqrt(squareNumber).toString();
26272+
expect(root).to.be.a("string");
26273+
expect(root).to.equal("0");
26274+
26275+
squareNumber = "-105625";
26276+
root = BigDecimal.sqrt(squareNumber).toString();
26277+
expect(root).to.be.a("string");
26278+
expect(root).to.equal("NaN");
26279+
26280+
squareNumber = "105625";
26281+
root = BigDecimal.sqrt(squareNumber).toString();
26282+
expect(root).to.be.a("string");
26283+
// expect(root).to.equal("325");
26284+
expect(
26285+
Math.abs(
26286+
Number(new BigDecimal(root).subtract(new BigDecimal("325")).toString())
26287+
)
26288+
).to.be.lte(1e-18);
26289+
26290+
squareNumber = "9";
26291+
root = BigDecimal.sqrt(squareNumber).toString();
26292+
expect(root).to.be.a("string");
26293+
// expect(root).to.equal("3");
26294+
expect(
26295+
Math.abs(
26296+
Number(new BigDecimal(root).subtract(new BigDecimal("3")).toString())
26297+
)
26298+
).to.be.lte(1e-18);
26299+
26300+
squareNumber = "3.14";
26301+
root = BigDecimal.sqrt(squareNumber).toString();
26302+
expect(root).to.be.a("string");
26303+
// expect(root).to.equal("1.772004514666935040");
26304+
expect(
26305+
Math.abs(
26306+
Number(
26307+
new BigDecimal(root)
26308+
.subtract(new BigDecimal("1.772004514666935040"))
26309+
.toString()
26310+
)
26311+
)
26312+
).to.be.lte(1e-18);
26313+
26314+
squareNumber = "102448.6";
26315+
root = BigDecimal.sqrt(squareNumber).toString();
26316+
expect(root).to.be.a("string");
26317+
// expect(root).to.equal("320.075928491975166214");
26318+
expect(
26319+
Math.abs(
26320+
Number(
26321+
new BigDecimal(root)
26322+
.subtract(new BigDecimal("320.075928491975166214"))
26323+
.toString()
26324+
)
26325+
)
26326+
).to.be.lte(1e-18);
26327+
26328+
squareNumber = "516699783";
26329+
root = BigDecimal.sqrt(squareNumber).toString();
26330+
expect(root).to.be.a("string");
26331+
// expect(root).to.equal("320.075928491975166214");
26332+
expect(
26333+
Math.abs(
26334+
Number(
26335+
new BigDecimal(root)
26336+
.subtract(new BigDecimal("22731.031278848744745528"))
26337+
.toString()
26338+
)
26339+
)
26340+
).to.be.lte(1e-18);
26341+
2626726342
document.querySelector("body").innerHTML = "All tests passed!";
2626826343
</script>
2626926344
</html>

test/test.js

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const chai = require("chai");
22
const JBC = require("../dist/jsbi-calculator.js");
33

44
const { assert, expect } = chai;
5-
const { calculator, arrayizeExpression, rpnParse, jsbiCal } = JBC;
5+
const { calculator, arrayizeExpression, rpnParse, jsbiCal, BigDecimal } = JBC;
66

77
let expression;
88

@@ -26240,3 +26240,77 @@ result = jsbiCal(rpn);
2624026240

2624126241
expect(result).to.be.a("string");
2624226242
expect(result).to.equal("0");
26243+
26244+
let squareNumber, root;
26245+
26246+
squareNumber = "0";
26247+
root = BigDecimal.sqrt(squareNumber).toString();
26248+
expect(root).to.be.a("string");
26249+
expect(root).to.equal("0");
26250+
26251+
squareNumber = "-105625";
26252+
root = BigDecimal.sqrt(squareNumber).toString();
26253+
expect(root).to.be.a("string");
26254+
expect(root).to.equal("NaN");
26255+
26256+
squareNumber = "105625";
26257+
root = BigDecimal.sqrt(squareNumber).toString();
26258+
expect(root).to.be.a("string");
26259+
// expect(root).to.equal("325");
26260+
expect(
26261+
Math.abs(
26262+
Number(new BigDecimal(root).subtract(new BigDecimal("325")).toString())
26263+
)
26264+
).to.be.lte(1e-18);
26265+
26266+
squareNumber = "9";
26267+
root = BigDecimal.sqrt(squareNumber).toString();
26268+
expect(root).to.be.a("string");
26269+
// expect(root).to.equal("3");
26270+
expect(
26271+
Math.abs(
26272+
Number(new BigDecimal(root).subtract(new BigDecimal("3")).toString())
26273+
)
26274+
).to.be.lte(1e-18);
26275+
26276+
squareNumber = "3.14";
26277+
root = BigDecimal.sqrt(squareNumber).toString();
26278+
expect(root).to.be.a("string");
26279+
// expect(root).to.equal("1.772004514666935040");
26280+
expect(
26281+
Math.abs(
26282+
Number(
26283+
new BigDecimal(root)
26284+
.subtract(new BigDecimal("1.772004514666935040"))
26285+
.toString()
26286+
)
26287+
)
26288+
).to.be.lte(1e-18);
26289+
26290+
squareNumber = "102448.6";
26291+
root = BigDecimal.sqrt(squareNumber).toString();
26292+
expect(root).to.be.a("string");
26293+
// expect(root).to.equal("320.075928491975166214");
26294+
expect(
26295+
Math.abs(
26296+
Number(
26297+
new BigDecimal(root)
26298+
.subtract(new BigDecimal("320.075928491975166214"))
26299+
.toString()
26300+
)
26301+
)
26302+
).to.be.lte(1e-18);
26303+
26304+
squareNumber = "516699783";
26305+
root = BigDecimal.sqrt(squareNumber).toString();
26306+
expect(root).to.be.a("string");
26307+
// expect(root).to.equal("320.075928491975166214");
26308+
expect(
26309+
Math.abs(
26310+
Number(
26311+
new BigDecimal(root)
26312+
.subtract(new BigDecimal("22731.031278848744745528"))
26313+
.toString()
26314+
)
26315+
)
26316+
).to.be.lte(1e-18);

test/test.mjs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { assert, expect } from "chai";
22
import JBC from "../dist/jsbi-calculator.mjs";
33

4-
const { calculator, arrayizeExpression, rpnParse, jsbiCal } = JBC;
4+
const { calculator, arrayizeExpression, rpnParse, jsbiCal, BigDecimal } = JBC;
55

66
let expression;
77

@@ -26239,3 +26239,77 @@ result = jsbiCal(rpn);
2623926239

2624026240
expect(result).to.be.a("string");
2624126241
expect(result).to.equal("0");
26242+
26243+
let squareNumber, root;
26244+
26245+
squareNumber = "0";
26246+
root = BigDecimal.sqrt(squareNumber).toString();
26247+
expect(root).to.be.a("string");
26248+
expect(root).to.equal("0");
26249+
26250+
squareNumber = "-105625";
26251+
root = BigDecimal.sqrt(squareNumber).toString();
26252+
expect(root).to.be.a("string");
26253+
expect(root).to.equal("NaN");
26254+
26255+
squareNumber = "105625";
26256+
root = BigDecimal.sqrt(squareNumber).toString();
26257+
expect(root).to.be.a("string");
26258+
// expect(root).to.equal("325");
26259+
expect(
26260+
Math.abs(
26261+
Number(new BigDecimal(root).subtract(new BigDecimal("325")).toString())
26262+
)
26263+
).to.be.lte(1e-18);
26264+
26265+
squareNumber = "9";
26266+
root = BigDecimal.sqrt(squareNumber).toString();
26267+
expect(root).to.be.a("string");
26268+
// expect(root).to.equal("3");
26269+
expect(
26270+
Math.abs(
26271+
Number(new BigDecimal(root).subtract(new BigDecimal("3")).toString())
26272+
)
26273+
).to.be.lte(1e-18);
26274+
26275+
squareNumber = "3.14";
26276+
root = BigDecimal.sqrt(squareNumber).toString();
26277+
expect(root).to.be.a("string");
26278+
// expect(root).to.equal("1.772004514666935040");
26279+
expect(
26280+
Math.abs(
26281+
Number(
26282+
new BigDecimal(root)
26283+
.subtract(new BigDecimal("1.772004514666935040"))
26284+
.toString()
26285+
)
26286+
)
26287+
).to.be.lte(1e-18);
26288+
26289+
squareNumber = "102448.6";
26290+
root = BigDecimal.sqrt(squareNumber).toString();
26291+
expect(root).to.be.a("string");
26292+
// expect(root).to.equal("320.075928491975166214");
26293+
expect(
26294+
Math.abs(
26295+
Number(
26296+
new BigDecimal(root)
26297+
.subtract(new BigDecimal("320.075928491975166214"))
26298+
.toString()
26299+
)
26300+
)
26301+
).to.be.lte(1e-18);
26302+
26303+
squareNumber = "516699783";
26304+
root = BigDecimal.sqrt(squareNumber).toString();
26305+
expect(root).to.be.a("string");
26306+
// expect(root).to.equal("320.075928491975166214");
26307+
expect(
26308+
Math.abs(
26309+
Number(
26310+
new BigDecimal(root)
26311+
.subtract(new BigDecimal("22731.031278848744745528"))
26312+
.toString()
26313+
)
26314+
)
26315+
).to.be.lte(1e-18);

0 commit comments

Comments
 (0)