Skip to content

Commit 838a5dd

Browse files
committed
Improve JSDoc documentation
1 parent ac23da6 commit 838a5dd

28 files changed

+205
-134
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# cmath-js
2-
Implementation of parts of C's & C++'s numerics libraries in TypeScript/JavaScript.
2+
Implementation of parts of C++'s numerics libraries in TypeScript/JavaScript, including functions C++ inherits from C.
33

44
## Floating-point functions
55
- [`copysign`](https://en.cppreference.com/w/c/numeric/math/copysign)
@@ -50,6 +50,6 @@ These functions accept either a `bigint` or an integer `number`:
5050
The test coverage is a perfect 100% and enforced by the publishing and pull request verification workflows.
5151

5252
## Contributing
53-
Contributions are welcomed! Feel free to make a pull request. Please add your name to `contributors` in `package.json` and run `npm run build-and-verify` before submitting your PR. By making a pull request you agree to license your contribution under [the CC0 license](https://creativecommons.org/publicdomain/zero/1.0/legalcode.en#legal-code-title) unless otherwise specified.
53+
Contributions are welcomed! Feel free to make a pull request. Please add your name to `contributors` in `package.json` and run `npm run build-and-verify` before submitting your PR. By opening a pull request you agree to license your contribution under [the CC0 license](https://creativecommons.org/publicdomain/zero/1.0/legalcode.en#legal-code-title) unless you specify otherwise.
5454

55-
ESLint is used to enforce code quality and consistent formatting (with the help of Prettier). If ESLint complains when you run `npm run build-and-verify`, you can run `npm run lint-fix` to apply automatic fixes and then fix the rest of the errors manually. I recommend configuring your IDE for ESLint and Prettier. If you are using Visual Studio Code, simply installing [Microsoft's ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [the official Prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) takes care of that.
55+
ESLint is used to enforce code quality and consistent formatting (with the help of Prettier). If ESLint complains when you run `npm run build-and-verify`, you can run `npm run lint-fix` to apply automatic fixes, and then fix the rest of the errors manually. It is recommend to configure your IDE for ESLint and Prettier. If you are using Visual Studio Code, simply installing [Microsoft's ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [the official Prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) takes care of that.

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/internal/floatOctets.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Constructing these can take a little bit of time so let's reuse them
22
const floatArray = new Float64Array(1);
3-
const octets = new Uint8Array(floatArray.buffer);
3+
const octets: Uint8Array = new Uint8Array(floatArray.buffer);
44

55
// DO NOT STORE THE Uint8Array RETURN VALUE FROM THIS CALL!
66
// It will be mutated on the next call to this function
7-
export function floatOctets(num: number): Readonly<Uint8Array> {
7+
export function floatOctets(num: number): Readonly<Uint8Array & { length: 8 }> {
88
floatArray[0] = num;
99
return octets;
1010
}

src/namespace-std-numbers/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// Mathematical constants defined in the namespace std::numbers
22
// cppreference: https://en.cppreference.com/w/cpp/numeric/constants
33

4-
export const e = Math.E;
4+
export const e: number = Math.E;
55
export const egamma = 0.5772156649015329; // The Euler-Mascheroni constant
66
export const inv_pi = 0.3183098861837907; // 1 / pi
77
export const inv_sqrt3 = 0.5773502691896257; // 1 / sqrt(3)
88
export const inv_sqrtpi = 0.5641895835477563; // 1 / sqrt(pi)
9-
export const ln10 = Math.LN10;
10-
export const ln2 = Math.LN2;
11-
export const log10 = Math.LOG10E;
12-
export const log2e = Math.LOG2E;
9+
export const ln10: number = Math.LN10;
10+
export const ln2: number = Math.LN2;
11+
export const log10: number = Math.LOG10E;
12+
export const log2e: number = Math.LOG2E;
1313
export const phi = 1.618033988749895; // The golden ratio
14-
export const pi = Math.PI;
15-
export const sqrt2 = Math.SQRT2;
14+
export const pi: number = Math.PI;
15+
export const sqrt2: number = Math.SQRT2;
1616
export const sqrt3 = 1.7320508075688772; // sqrt(3)

src/namespace-std/all-numbers/iota.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
// Fills an array with sequentially increasing values
2-
// Cppreference: https://en.cppreference.com/w/c/numeric/math/iota
3-
1+
/**
2+
* Fills an array with sequentially increasing values
3+
*
4+
* Read more about the original function on
5+
* - {@link https://en.cppreference.com/w/c/numeric/math/iota|Cppreference}
6+
*/
47
export function iota(mut_arrayToFill: bigint[], startValue: bigint): void;
58
export function iota(mut_arrayToFill: number[], startValue: number): void;
69
export function iota(mut_arrayToFill: (bigint | number)[], startValue: bigint | number): void {
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { floatOctets } from "../../internal/index.js";
2-
3-
// Cppreference: https://en.cppreference.com/w/c/numeric/math/signbit
2+
/**
3+
* Determines if a number is negative or NaN with the sign bit set.
4+
* Note that the ECMAScript standard does not guarantee that +NaN and
5+
* -NaN are different so this function may give unexpected results
6+
* (such as always false or always true) in some JavaScript engines.
7+
*
8+
* Read more about the original function on
9+
* - {@link https://en.cppreference.com/w/cpp/numeric/math/signbit|Cppreference}
10+
*/
411
export function signbit(num: bigint | number): boolean {
512
return floatOctets(Number(num))[7] > 127;
613
}
Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import { signbit } from "../index.js";
22

3-
// copysign produces a value with the magnitude of 'num' and the sign 'sign'
4-
// C spec: https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf#subsection.7.12.11
5-
// Cppreference: https://en.cppreference.com/w/c/numeric/math/copysign
6-
// This implementation handles positive and negative zero and positive and negative
7-
// NaNs (in JS engines where that difference is observable when writing NaNs to a Float64Array)
8-
export function copysign(/*double*/ num: number, /*double*/ sign: number): /*double*/ number {
3+
/**
4+
* Produces a value with the magnitude of 'num' and the sign 'sign'.
5+
* This implementation handles positive and negative zero and positive and negative
6+
* NaNs (in JS engines where that difference is observable when writing NaNs to a Float64Array).
7+
*
8+
* Read more about the original function on
9+
* - {@link https://en.cppreference.com/w/cpp/numeric/math/copysign|Cppreference}
10+
* - {@link https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf#subsection.7.12.11|The C23 final draft specification}
11+
*/
12+
13+
export function copysign(num: number, sign: number): number {
914
return signbit(num) === signbit(sign) ? num : -num;
1015
}

src/namespace-std/doubles/fabs.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1-
// fabs is just like JavaScript's Math.abs
2-
// Cppreference: https://en.cppreference.com/w/c/numeric/math/fabs
3-
export const fabs = Math.abs;
1+
/**
2+
* fabs is just like JavaScript's Math.abs.
3+
*
4+
* Read more about the original function on
5+
* - {@link https://en.cppreference.com/w/cpp/numeric/math/fabs|Cppreference}
6+
*/
7+
8+
export const fabs: (number: number) => number = Math.abs;

src/namespace-std/doubles/frexp.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { frexp } from "./index.js";
22

33
describe(frexp.name, () => {
44
it("decomposes a number into a normalized fraction and an integral power of two", () => {
5-
expect(frexp(1)).toStrictEqual([0.5, 1]);
6-
expect(frexp(1.5)).toStrictEqual([0.75, 1]);
7-
expect(frexp(3 * 2 ** 500)).toStrictEqual([0.75, 502]);
8-
expect(frexp(-4)).toStrictEqual([-0.5, 3]);
9-
expect(frexp(Number.MAX_VALUE)).toStrictEqual([0.9999999999999999, 1024]);
10-
expect(frexp(Number.MIN_VALUE)).toStrictEqual([0.5, -1073]);
11-
expect(frexp(-Infinity)).toStrictEqual([-Infinity, 0]);
12-
expect(frexp(-0)).toStrictEqual([-0, 0]);
13-
expect(frexp(NaN)).toStrictEqual([NaN, 0]);
5+
expect(frexp(1)).toStrictEqual({ exponent: 1, fraction: 0.5 });
6+
expect(frexp(1.5)).toStrictEqual({ exponent: 1, fraction: 0.75 });
7+
expect(frexp(3 * 2 ** 500)).toStrictEqual({ exponent: 502, fraction: 0.75 });
8+
expect(frexp(-4)).toStrictEqual({ exponent: 3, fraction: -0.5 });
9+
expect(frexp(Number.MAX_VALUE)).toStrictEqual({ exponent: 1024, fraction: 0.9999999999999999 });
10+
expect(frexp(Number.MIN_VALUE)).toStrictEqual({ exponent: -1073, fraction: 0.5 });
11+
expect(frexp(-Infinity)).toStrictEqual({ exponent: 0, fraction: -Infinity });
12+
expect(frexp(-0)).toStrictEqual({ exponent: 0, fraction: -0 });
13+
expect(frexp(NaN)).toStrictEqual({ exponent: 0, fraction: NaN });
1414
});
1515
});

src/namespace-std/doubles/frexp.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,45 @@
1-
// Note: Instead of "double frexp(double arg, int* exp)" this is built as "[double, int] frexp(double arg)" due to ECMAScripts's lack of pointers
2-
// A hypothetical issue with this implementation is that the precision the ** operator is not defined in the ECMAScript standard,
3-
// however, sane ECMAScript implementations should give precise results for 2**<integer> expressions
4-
// Cppreference: https://en.cppreference.com/w/c/numeric/math/frexp for a more detailed description
1+
export interface frexp_result {
2+
exponent: number;
3+
fraction: number;
4+
}
5+
6+
// Note: Instead of "double frexp(double arg, int* exp)" this is built as "{ exponent, fraction } frexp(double arg)" due to ECMAScripts's lack of pointers
7+
// A hypothetical issue with this implementation is that the precision of the ** operator is not defined in the ECMAScript standard,
8+
// however, it is hard to imagine a sane ECMAScript implementation would give imprecise results for 2**<integer> expressions.
9+
// Cppreference: https://en.cppreference.com/w/cpp/numeric/math/frexp
510
// Object.is(n, frexp(n)[0] * 2 ** frexp(n)[1]) for all number values of n except when Math.isFinite(n) && Math.abs(n) > 2**1023
611
// Object.is(n, (2 * frexp(n)[0]) * 2 ** (frexp(n)[1] - 1)) for all number values of n
712
// Object.is(n, frexp(n)[0]) for these values of n: 0, -0, NaN, Infinity, -Infinity
813
// Math.abs(frexp(n)[0]) is >= 0.5 and < 1.0 for any other number-type value of n
9-
export function frexp(
10-
/*double*/ num: number,
11-
): [/*double*/ fraction: number, /*int*/ exponent: number] {
14+
export function frexp(num: number): frexp_result {
1215
if (num === 0 || !Number.isFinite(num)) {
13-
return [num, 0];
16+
return { exponent: 0, fraction: num };
1417
}
1518

1619
const absNum: number = Math.abs(num);
1720

18-
let exp: number = Math.max(-1023, Math.floor(Math.log2(absNum)) + 1);
19-
let x: number = absNum * 2 ** -exp;
21+
let exponent: number = Math.max(-1023, Math.floor(Math.log2(absNum)) + 1);
22+
let fraction: number = absNum * 2 ** -exponent;
2023

2124
// These while loops compensate for rounding errors that may occur because of ECMAScript's Math.log2's undefined precision
2225
// and the first one also helps work around the issue of 2 ** -exp === Infinity when exp <= -1024
23-
while (x < 0.5) {
24-
x *= 2;
25-
--exp;
26+
while (fraction < 0.5) {
27+
fraction *= 2;
28+
--exponent;
2629
}
2730

2831
// istanbul ignore next - This might never run and that's okay. See the above comment
29-
while (x >= 1) {
30-
x *= 0.5;
31-
++exp;
32+
while (fraction >= 1) {
33+
fraction *= 0.5;
34+
++exponent;
3235
}
3336

3437
if (num < 0) {
35-
x = -x;
38+
fraction = -fraction;
3639
}
3740

38-
return [x, exp];
41+
return {
42+
exponent,
43+
fraction,
44+
};
3945
}

0 commit comments

Comments
 (0)