Skip to content

Commit b8469a2

Browse files
authored
Merge pull request #10 from nberlette/refactor-everything
refactor: everything
2 parents e1ff9e6 + 80cc321 commit b8469a2

22 files changed

Lines changed: 673 additions & 139 deletions

README.md

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,42 @@
88

99
---
1010

11-
This is project implements all of the `Math.*` functions in JavaScript without
12-
using the built-in `Math` object. For what reason would I do such a thing? Well,
13-
that remains to be seen.
14-
15-
I cannot guarantee the accuracy of all of these functions. I **_can_** guarantee
16-
the accuracy of the [constants](#constants) and the [guards](#guards), however.
17-
18-
If you find an issue with the logic behind any of the functions, please
19-
[open an issue](https://github.com/nberlette/math/issues/new) so that I can
20-
address it promptly. Thanks!
21-
22-
---
11+
## Overview
12+
13+
Standalone implementations of the **entire** native [`Math`] namespace, written
14+
in pure TypeScript with absolutely zero dependencies. Organized in a modular
15+
structure to encourage tree-shaking (dead code elimination) in bundlers, this
16+
package can be imported eithr on an individual module basis, or as a namespace
17+
suitable for use as a drop-in replacement for the standard `Math` object[^1].
18+
19+
[^1]: All modules in this package are implemented using 100% manual logic and
20+
arithmetic, and do not rely on any native code or objects. As such, the
21+
performance will typically be slightly slower than the native `Math.*`
22+
implementations. There may also be some minor deviations in output. If you
23+
believe a specific function is inaccurate or otherwise inconsistent with the
24+
expected behavior, please open an issue so I can address it and attempt to
25+
improve it. Thank you!
2326

2427
## Install
2528

2629
```sh
27-
deno add @nick/math
30+
deno add jsr:@nick/math
2831
```
2932

3033
```sh
31-
bunx jsr add @nick/math
34+
pnpm add jsr:@nick/math
3235
```
3336

3437
```sh
35-
pnpm dlx jsr add @nick/math
38+
yarn add jsr:@nick/math
3639
```
3740

3841
```sh
39-
npx jsr add @nick/math
42+
bunx jsr add @nick/math
4043
```
4144

4245
```sh
43-
yarn dlx jsr add @nick/math
46+
npx jsr add @nick/math
4447
```
4548

4649
---
@@ -933,15 +936,20 @@ console.assert(isNegativeInfinity(-Infinity));
933936

934937
<div align="center">
935938

936-
#### [MIT] © [Nicholas Berlette]. All rights reserved.
939+
**[MIT] © [Nicholas Berlette]. All rights reserved.**
937940

938-
###### [GitHub] · [Issues] · [JSR] · [NPM]
941+
<small>
939942

940-
</div>
943+
[github] · [issues] · [jsr] · [npm] · [contributing]
944+
945+
</small></div>
941946

942947
[MIT]: https://nick.mit-license.org "MIT © Nicholas Berlette. All rights reserved."
943-
[Nicholas Berlette]: https://nick.berlette.com "Nicholas Berlette"
944-
[GitHub]: https://github.com/nberlette/math "View @nick/math on GitHub"
945-
[Issues]: https://github.com/nberlette/math/issues "Found a bug? Let's squash it!"
946-
[JSR]: https://jsr.io/@nick/math/doc "View @nick/math on JSR"
948+
[Nicholas Berlette]: https://github.com/nberlette "Follow nberlette on GitHub for more cool stuff!"
949+
[GitHub]: https://github.com/nberlette/math "Give nberlette/math a star on GitHub! ⭐️"
950+
[Issues]: https://github.com/nberlette/math/issues "Found a bug? Let's squash it! 🐛"
951+
[JSR]: https://jsr.io/@nick/math "View the @nick/math package on JSR"
952+
[docs]: https://jsr.io/@nick/math/doc "View auto-generated API documentation for @nick/math on JSR"
947953
[NPM]: https://npmjs.com/package/@nberlette/math "View @nberlette/math on NPM"
954+
[contributing]: https://github.com/nberlette/math/blob/main/.github/CONTRIBUTING.md "Contribution guidelines"
955+
[`Math`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math

deno.json

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
"./clz32": "./src/clz32.ts",
2424
"./cos": "./src/cos.ts",
2525
"./cosh": "./src/cosh.ts",
26+
"./e": "./src/constants/e.ts",
27+
"./epsilon": "./src/constants/epsilon.ts",
2628
"./exp": "./src/exp.ts",
2729
"./expm1": "./src/expm1.ts",
2830
"./f16round": "./src/f16round.ts",
@@ -32,12 +34,20 @@
3234
"./ieee754": "./src/ieee754.ts",
3335
"./imul": "./src/imul.ts",
3436
"./infinity": "./src/guards/infinity.ts",
37+
"./ln2": "./src/constants/ln2.ts",
38+
"./ln10": "./src/constants/ln10.ts",
3539
"./log": "./src/log.ts",
3640
"./log1p": "./src/log1p.ts",
3741
"./log2": "./src/log2.ts",
42+
"./log2e": "./src/constants/log2e.ts",
3843
"./log10": "./src/log10.ts",
44+
"./log10e": "./src/constants/log10e.ts",
3945
"./max": "./src/max.ts",
46+
"./max-safe-integer": "./src/constants/max_safe_integer.ts",
47+
"./max-value": "./src/constants/max_value.ts",
4048
"./min": "./src/min.ts",
49+
"./min-safe-integer": "./src/constants/min_safe_integer.ts",
50+
"./min-value": "./src/constants/min_value.ts",
4151
"./nan": "./src/guards/nan.ts",
4252
"./pi": "./src/constants/pi.ts",
4353
"./pow": "./src/pow.ts",
@@ -47,6 +57,9 @@
4757
"./sin": "./src/sin.ts",
4858
"./sinh": "./src/sinh.ts",
4959
"./sqrt": "./src/sqrt.ts",
60+
"./sqrt1_2": "./src/constants/sqrt1_2.ts",
61+
"./sqrt1-2": "./src/constants/sqrt1_2.ts",
62+
"./sqrt2": "./src/constants/sqrt2.ts",
5063
"./tan": "./src/tan.ts",
5164
"./tanh": "./src/tanh.ts",
5265
"./trunc": "./src/trunc.ts",
@@ -67,34 +80,40 @@
6780
"./constants/pi": "./src/constants/pi.ts",
6881
"./constants/positive-infinity": "./src/constants/positive_infinity.ts",
6982
"./constants/positive-zero": "./src/constants/positive_zero.ts",
83+
"./constants/sqrt1_2": "./src/constants/sqrt1_2.ts",
7084
"./constants/sqrt1-2": "./src/constants/sqrt1_2.ts",
7185
"./constants/sqrt2": "./src/constants/sqrt2.ts",
7286
"./float16": "./src/float16/mod.ts",
73-
"./float16/encode": "./src/float16/encode.ts",
87+
"./float16/constants": "./src/float16/constants.ts",
7488
"./float16/decode": "./src/float16/decode.ts",
89+
"./float16/encode": "./src/float16/encode.ts",
90+
"./float16/guards": "./src/float16/guards.ts",
7591
"./float16/round": "./src/float16/round.ts",
7692
"./float32": "./src/float32/mod.ts",
77-
"./float32/encode": "./src/float32/encode.ts",
93+
"./float32/constants": "./src/float32/constants.ts",
7894
"./float32/decode": "./src/float32/decode.ts",
95+
"./float32/encode": "./src/float32/encode.ts",
96+
"./float32/guards": "./src/float32/guards.ts",
7997
"./float32/round": "./src/float32/round.ts",
8098
"./guards": "./src/guards/mod.ts",
8199
"./guards/finite": "./src/guards/finite.ts",
82100
"./guards/infinity": "./src/guards/infinity.ts",
83-
"./guards/positive-infinity": "./src/guards/positive_infinity.ts",
101+
"./guards/integer": "./src/guards/integer.ts",
102+
"./guards/nan": "./src/guards/nan.ts",
84103
"./guards/negative-infinity": "./src/guards/negative_infinity.ts",
85104
"./guards/negative-zero": "./src/guards/negative_zero.ts",
105+
"./guards/positive-infinity": "./src/guards/positive_infinity.ts",
86106
"./guards/positive-zero": "./src/guards/positive_zero.ts",
87-
"./guards/integer": "./src/guards/integer.ts",
88107
"./guards/safe-integer": "./src/guards/safe_integer.ts",
89-
"./guards/nan": "./src/guards/nan.ts",
90108
"./is/finite": "./src/guards/finite.ts",
91109
"./is/infinity": "./src/guards/infinity.ts",
92-
"./is/positive-infinity": "./src/guards/positive_infinity.ts",
110+
"./is/integer": "./src/guards/integer.ts",
111+
"./is/nan": "./src/guards/nan.ts",
93112
"./is/negative-infinity": "./src/guards/negative_infinity.ts",
94113
"./is/negative-zero": "./src/guards/negative_zero.ts",
95-
"./is/integer": "./src/guards/integer.ts",
114+
"./is/positive-infinity": "./src/guards/positive_infinity.ts",
115+
"./is/positive-zero": "./src/guards/positive_zero.ts",
96116
"./is/safe-integer": "./src/guards/safe_integer.ts",
97-
"./is/nan": "./src/guards/nan.ts",
98117
"./types": "./src/types/mod.ts",
99118
"./types/finite": "./src/types/finite.ts",
100119
"./types/float": "./src/types/float.ts",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as constants from "../src/constants/mod.ts";
1+
import * as constants from "./constants/mod.ts";
22
import { describe, it } from "@std/testing/bdd";
33
import { expect } from "@std/expect";
44

src/constants/positive_zero.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ interface PositiveZero {
2828
* ```ts
2929
* import { POSITIVE_ZERO } from "@nick/math/constants/positive-zero";
3030
* import { isPositiveZero } from "@nick/math/is/positive-zero";
31+
* import assert from "node:assert";
3132
*
32-
* ]
33+
* assert.strictEqual(isPositiveZero(-0), false); // OK
34+
* assert.strictEqual(isPositiveZero(POSITIVE_ZERO), true); // OK
35+
* assert.strictEqual(POSITIVE_ZERO, 0); // OK
3336
* ```
3437
*/
3538
export const POSITIVE_ZERO: POSITIVE_ZERO = 0 as POSITIVE_ZERO;

src/exp.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import { abs } from "./abs.ts";
2222
* import { assertEquals } from "@std/assert";
2323
*
2424
* assertEquals(exp(0), 1);
25-
* assertEquals(exp(1), 2.718281828459045);
26-
* assertEquals(exp(2), 7.3890560989306495);
25+
* assertEquals(exp(1), 2.7182818284590455);
26+
* assertEquals(exp(2), 7.389056098930649);
2727
* ```
2828
*/
2929
export function exp(x: number): number {

src/float16/constants.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* This module provides constants used by the encoding/decoding APIs in the
3+
* `@nick/math/float16` suite. These are primarily used to handle special cases
4+
* such as `NaN`, `Infinity`, and `-0`, which have unique representations in
5+
* the IEEE-754 half-precision floating point format.
6+
*
7+
* These are intended for primarily internal use, but are exported for the sake
8+
* of completeness and transparency, as well as for potential userland usage in
9+
* cases where the constants are needed for custom encoding/decoding logic.
10+
*
11+
* @module float16/constants
12+
*/
13+
14+
/**
15+
* Well-known bit pattern representing `NaN` in the IEEE-754 half-precision (or
16+
* "binary16") format.
17+
*
18+
* @category Constants
19+
* @tags float16, ieee-754, NaN
20+
*/
21+
export const FLOAT16_NAN = 0x7E00;
22+
23+
/**
24+
* Well-known bit pattern representing `+Infinity` (positive infinity) in the
25+
* IEEE-754 half-precision (or "binary16") format.
26+
*
27+
* @category Constants
28+
* @tags float16, ieee-754, Infinity
29+
*/
30+
export const FLOAT16_POSITIVE_INFINITY = 0x7C00;
31+
32+
/**
33+
* Well-known bit pattern representing `-Infinity` (negative infinity) in the
34+
* IEEE-754 half-precision (or "binary16") format.
35+
*
36+
* @category Constants
37+
* @tags float16, ieee-754, Infinity
38+
*/
39+
export const FLOAT16_NEGATIVE_INFINITY = 0xFC00;
40+
41+
/**
42+
* Well-known bit pattern representing `-0` (negative zero) in the IEEE-754
43+
* half-precision (or "binary16") format.
44+
*
45+
* @category Constants
46+
* @tags float16, ieee-754, zero
47+
*/
48+
export const FLOAT16_NEGATIVE_ZERO = 0x8000;
49+
50+
/**
51+
* Well-known bit pattern representing `+0` (positive zero) in the IEEE-754
52+
* half-precision (or "binary16") format.
53+
*
54+
* **Note**: This constant, unlike the others, is equivalent to its bit pattern
55+
* representation (all bits are zero). As such, this is not strictly necessary
56+
* for encoding/decoding, but is included for completeness and consistency.
57+
*
58+
* @category Constants
59+
* @tags float16, ieee-754, zero
60+
*/
61+
export const FLOAT16_POSITIVE_ZERO = 0x0000;
62+
63+
/**
64+
* The number of bits used for the exponent in the IEEE-754 half-precision
65+
* (or "binary16") format.
66+
*
67+
* @category Constants
68+
* @tags float16, ieee-754, exponent
69+
*/
70+
export const FLOAT16_EXPONENT_BITS = 5;
71+
72+
/**
73+
* The number of bits used for the mantissa in the IEEE-754 half-precision
74+
* (or "binary16") format.
75+
*
76+
* @category Constants
77+
* @tags float16, ieee-754, mantissa
78+
*/
79+
export const FLOAT16_MANTISSA_BITS = 10;
80+
81+
/**
82+
* The exponent bias used in the IEEE-754 half-precision (or "binary16")
83+
* format.
84+
*
85+
* @category Constants
86+
* @tags float16, ieee-754, bias
87+
*/
88+
export const FLOAT16_EXPONENT_BIAS = 15;

src/float16/decode.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@
1515
*
1616
* @module float16/decode
1717
*/
18-
import { POSITIVE_INFINITY } from "../constants/positive_infinity.ts";
19-
import { NEGATIVE_INFINITY } from "../constants/negative_infinity.ts";
20-
import { NAN } from "../constants/nan.ts";
21-
import { pow } from "../pow.ts";
18+
import {
19+
FLOAT16_EXPONENT_BIAS,
20+
FLOAT16_EXPONENT_BITS,
21+
FLOAT16_MANTISSA_BITS,
22+
FLOAT16_NAN,
23+
FLOAT16_NEGATIVE_INFINITY,
24+
FLOAT16_NEGATIVE_ZERO,
25+
FLOAT16_POSITIVE_INFINITY,
26+
FLOAT16_POSITIVE_ZERO,
27+
} from "./constants.ts";
28+
import { decode } from "../internal/ieee754.ts";
2229

2330
/**
2431
* Decodes a 16-bit unsigned integer (`Uint16`) into a 16-bit half-precision
@@ -59,18 +66,14 @@ import { pow } from "../pow.ts";
5966
* @tags float, float16, decode
6067
*/
6168
export function decodeFloat16(bits: number): number {
62-
if (bits === 0x7E00) return NAN;
63-
if (bits === 0x7C00) return POSITIVE_INFINITY;
64-
if (bits === 0xFC00) return NEGATIVE_INFINITY;
65-
if (bits === 0x8000) return -0;
66-
if (bits === 0) return 0;
67-
68-
const sign = ((bits >> 15) & 0x1) ? -1 : 1;
69-
const expo = (bits >> 10) & 0x1F;
70-
const mant = bits & 0x3FF;
71-
72-
if (expo === 0) return sign * pow(2, -14) * (mant / pow(2, 10));
73-
if (expo === 0x1F) return sign * (mant ? NAN : POSITIVE_INFINITY);
74-
75-
return sign * pow(2, expo - 15) * (1 + mant / pow(2, 10));
69+
return decode(bits, {
70+
exponent: FLOAT16_EXPONENT_BITS,
71+
mantissa: FLOAT16_MANTISSA_BITS,
72+
bias: FLOAT16_EXPONENT_BIAS,
73+
nan: FLOAT16_NAN,
74+
positive_infinity: FLOAT16_POSITIVE_INFINITY,
75+
negative_infinity: FLOAT16_NEGATIVE_INFINITY,
76+
positive_zero: FLOAT16_POSITIVE_ZERO,
77+
negative_zero: FLOAT16_NEGATIVE_ZERO,
78+
});
7679
}

0 commit comments

Comments
 (0)