cmath-js 1.0.2 → 1.0.4

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.
Files changed (86) hide show
  1. package/.dockerignore +10 -0
  2. package/.editorconfig +7 -0
  3. package/.env +4 -0
  4. package/.eslintignore +2 -0
  5. package/.eslintrc.json +36 -0
  6. package/.gitattributes +1 -0
  7. package/.github/workflows/github-actions-verify.yml +22 -0
  8. package/.nvmrc +1 -0
  9. package/.prettierrc +10 -0
  10. package/.vscode/extensions.json +7 -0
  11. package/.vscode/launch.json +28 -14
  12. package/.vscode/settings.json +14 -0
  13. package/Dockerfile +11 -0
  14. package/LICENSE +1 -1
  15. package/README.md +14 -11
  16. package/dist/double/copysign.d.ts +1 -0
  17. package/dist/double/copysign.js +4 -0
  18. package/dist/double/copysign.js.map +1 -0
  19. package/dist/double/fabs.d.ts +1 -0
  20. package/dist/double/fabs.js +2 -0
  21. package/dist/double/fabs.js.map +1 -0
  22. package/dist/double/frexp.d.ts +1 -0
  23. package/dist/double/frexp.js +23 -0
  24. package/dist/double/frexp.js.map +1 -0
  25. package/dist/double/hypot.d.ts +1 -0
  26. package/dist/double/hypot.js +19 -0
  27. package/dist/double/hypot.js.map +1 -0
  28. package/dist/double/index.d.ts +8 -0
  29. package/dist/double/index.js +9 -0
  30. package/dist/double/index.js.map +1 -0
  31. package/dist/double/ldexp.d.ts +1 -0
  32. package/dist/double/ldexp.js +5 -0
  33. package/dist/double/ldexp.js.map +1 -0
  34. package/dist/double/nextafter.d.ts +1 -0
  35. package/dist/double/nextafter.js +22 -0
  36. package/dist/double/nextafter.js.map +1 -0
  37. package/dist/double/pow.d.ts +1 -0
  38. package/dist/double/pow.js +8 -0
  39. package/dist/double/pow.js.map +1 -0
  40. package/dist/double/signbit.d.ts +1 -0
  41. package/dist/double/signbit.js +4 -0
  42. package/dist/double/signbit.js.map +1 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +3 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/integer/abs.d.ts +1 -0
  47. package/dist/integer/abs.js +7 -0
  48. package/dist/integer/abs.js.map +1 -0
  49. package/dist/integer/index.d.ts +1 -0
  50. package/dist/integer/index.js +2 -0
  51. package/dist/integer/index.js.map +1 -0
  52. package/docker-compose.ci-verifier.yml +6 -0
  53. package/jest.config.js +12 -0
  54. package/jest.config.with-typechecking.js +9 -0
  55. package/package.json +48 -35
  56. package/src/double/copysign.test.ts +9 -0
  57. package/src/double/copysign.ts +8 -0
  58. package/src/double/fabs.test.ts +14 -0
  59. package/src/double/fabs.ts +3 -0
  60. package/src/double/frexp.test.ts +15 -0
  61. package/src/double/frexp.ts +40 -0
  62. package/src/double/hypot.test.ts +11 -0
  63. package/src/double/hypot.ts +25 -0
  64. package/src/double/index.ts +8 -0
  65. package/src/double/ldexp.test.ts +16 -0
  66. package/src/double/ldexp.ts +11 -0
  67. package/src/double/nextafter.test.ts +29 -0
  68. package/src/double/nextafter.ts +22 -0
  69. package/src/double/pow.test.ts +27 -0
  70. package/src/double/pow.ts +8 -0
  71. package/src/double/signbit.test.ts +13 -0
  72. package/src/double/signbit.ts +4 -0
  73. package/src/index.ts +11 -0
  74. package/src/integer/abs.test.ts +28 -0
  75. package/src/integer/abs.ts +8 -0
  76. package/src/integer/index.ts +1 -0
  77. package/suppressExperimentalWarnings.cjs +11 -0
  78. package/tsconfig.json +98 -17
  79. package/.vscode/ipch/5ab7b32c9fc14e9f/mmap_address.bin +0 -0
  80. package/.vscode/tasks.json +0 -22
  81. package/dist/cmath.d.ts +0 -9
  82. package/dist/cmath.js +0 -126
  83. package/dist/cmath.js.map +0 -1
  84. package/jest.config.json +0 -9
  85. package/src/cmath.ts +0 -146
  86. package/test/cmath.test.ts +0 -123
package/src/cmath.ts DELETED
@@ -1,146 +0,0 @@
1
- // These functions are JavaScript versions of math functions from C (version 2017) and C++ (version 2017)
2
- // They follow the rules for IEEE-754 implementations
3
- // References:
4
- // C17: https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf#subsection.13.10.4
5
- // C++17: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf
6
- // IEEE-754:2008 (IEC 60559): http://irem.univ-reunion.fr/IMG/pdf/ieee-754-2008.pdf
7
- // https://en.cppreference.com/
8
- // When reading this it's important to remember that 0 === -0, but Object.is(0, -0) === false
9
-
10
-
11
- // Cppreference: https://en.cppreference.com/w/c/numeric/math/nextafter
12
- export function nextafter(/*double*/ num : number, /*double*/ toward : number) : /*double*/ number {
13
- if(num === toward) {
14
- return toward;
15
- }
16
- if(num === 0) {
17
- return Math.sign(toward) * Number.MIN_VALUE;
18
- }
19
- if(num === Infinity || num === -Infinity) {
20
- return Number.MAX_VALUE * Math.sign(num);
21
- }
22
- if(num === -Number.MIN_VALUE && toward > num) {
23
- return -0;
24
- }
25
- let differenceMultiplier = 0.5 * Math.sign(num) * (num < toward ? 1 : -1);
26
- let result : number;
27
- do {
28
- result = num + num * (Number.EPSILON * differenceMultiplier);
29
- differenceMultiplier *= 2;
30
- } while(result === num);
31
- return result;
32
- }
33
-
34
-
35
- // Cppreference: https://en.cppreference.com/w/c/numeric/math/pow
36
- // ECMAScript ** operator: https://www.ecma-international.org/ecma-262/9.0/index.html#sec-applying-the-exp-operator
37
- export function pow(/*double*/ base : number, /*double*/ exponent : number) : /*double*/ number {
38
- let result = base ** exponent;
39
- if(base === 1 || (base === -1 && (exponent === Infinity || exponent === -Infinity))) {
40
- result = 1;
41
- }
42
- return result;
43
- }
44
-
45
-
46
- export function signbit(/*double*/ num : number) : boolean {
47
- return Object.is(num, -0) || num < 0;
48
- }
49
-
50
-
51
- // 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
52
- // A hypothetical issue with this implementation is that the precision the ** operator is not defined in the ECMAScript standard,
53
- // however, sane ECMAScript implementations should give precise results for 2**<integer> expressions
54
- // Cppreference: http://en.cppreference.com/w/c/numeric/math/frexp for a more detailed description
55
- // 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
56
- // Object.is(n, (2 * frexp(n)[0]) * 2 ** (frexp(n)[1] - 1)) for all number values of n
57
- // Object.is(n, frexp(n)[0]) for these values of n: 0, -0, NaN, Infinity, -Infinity
58
- // Math.abs(frexp(n)[0]) is >= 0.5 and < 1.0 for any other number-type value of n
59
- export function frexp(/*double*/ num : number) : [/*double*/ number, /*int*/ number] {
60
- const result : [number, number] = [num, 0];
61
-
62
- if(num !== 0 && Number.isFinite(num)) {
63
- const absNum : number = Math.abs(num);
64
-
65
- let exp : number = Math.max(-1023, Math.floor(Math.log2(absNum)) + 1);
66
- let x : number = absNum * 2 ** -exp;
67
-
68
- // These while loops compensate for rounding errors that may occur because of ECMAScript's Math.log2's undefined precision
69
- // and the first one also helps work around the issue of 2 ** -exp === Infinity when exp <= -1024
70
- while(x < 0.5) {
71
- x *= 2;
72
- --exp;
73
- }
74
-
75
- // istanbul ignore next This might not run and that's okay. See the above comment
76
- while(x >= 1) {
77
- x *= 0.5;
78
- ++exp;
79
- }
80
-
81
- if(num < 0) {
82
- x = -x;
83
- }
84
- result[0] = x;
85
- result[1] = exp;
86
- }
87
- return result;
88
- }
89
-
90
-
91
- // ldexp multiplies a floating-point number by an integral power of 2
92
- // ldexp returns factor * 2**exponent
93
- // 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.6
94
- // Cppreference: https://en.cppreference.com/w/c/numeric/math/ldexp
95
- // Implementation is complicated by the need to avoid underflow/overflow given a large exponent (-1075< >1023)
96
- export function ldexp(/*double*/ factor : number, /*int*/ exponent : number) : /*double*/ number {
97
- const halfPowerRoundedTowardZero : number = 2 ** Math.trunc(exponent * 0.5);
98
- return factor * halfPowerRoundedTowardZero * halfPowerRoundedTowardZero * 2 ** Math.sign(exponent % 2);
99
- }
100
-
101
-
102
- // copysign produces a value with the magnitude of 'num' and the sign 'sign'
103
- // Note: ECMAScript does not have negative NaNs
104
- // 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
105
- // Cppreference: https://en.cppreference.com/w/c/numeric/math/copysign
106
- // The implementation is complicated by the need to handle positive and negative zero
107
- export function copysign(/*double*/ num : number, /*double*/ sign : number) : /*double*/ number {
108
- return Math.abs(num) * (Object.is(0 * Math.sign(sign), -0) ? -1 : 1);
109
- }
110
-
111
-
112
- // fabs is just like JavaScript's Math.abs
113
- // Cppreference: https://en.cppreference.com/w/c/numeric/math/fabs
114
- export const fabs = Math.abs;
115
-
116
-
117
- // abs is like fabs but for integers
118
- // Cppreference: https://en.cppreference.com/w/c/numeric/math/abs
119
- export const abs = fabs;
120
-
121
-
122
- // hypot computes the square root of the sum of the squares of x and y, without undue overflow or underflow
123
- // This implementation allows an optional third argument, as specified in the C++ standard
124
- // 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.7
125
- // C spec: https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf#subsection.13.10.4
126
- // C++ spec for 3-arg version: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf#subsection.29.9.3
127
- // Cppreference C version (limited to 2 args): https://en.cppreference.com/w/c/numeric/math/hypot
128
- // Cppreference C++ version (2 or 3 args): https://en.cppreference.com/w/cpp/numeric/math/hypot
129
- // ECMAScript's Math.hypot: https://www.ecma-international.org/ecma-262/9.0/index.html#sec-math.hypot
130
- // Complicated by the requirements for implementations for IEC 60559 floating-point environments, which thankfully only apply to the 2-arg (C) version
131
- export function hypot(/*double*/ x : number, /*double*/ y : number, /*double*/ z ?: number) : number {
132
- let result : number = 0;
133
- if(z !== undefined) {
134
- result = Math.hypot(x, y, z);
135
- } else {
136
- result = Infinity;
137
- if(x !== Infinity && x !== -Infinity && y !== Infinity && y !== -Infinity) {
138
- if(x === 0 || y === 0) {
139
- result = Math.max(Math.abs(x), Math.abs(y));
140
- } else {
141
- result = Math.hypot(x, y);
142
- }
143
- }
144
- }
145
- return result;
146
- }
@@ -1,123 +0,0 @@
1
-
2
- import * as cmath from "../src/cmath"
3
-
4
- test("nextafter", () => {
5
- expect(cmath.nextafter(-3.5, 3.5)).toBe(-3.5 + Number.EPSILON * 2);
6
- expect(cmath.nextafter(1, 2)).toBe(1 + Number.EPSILON);
7
- expect(cmath.nextafter(3, 4)).toBe(3 + Number.EPSILON*2);
8
- expect(cmath.nextafter(3.5, 3.5)).toBe(3.5);
9
- expect(cmath.nextafter(-3.5, -3.5)).toBe(-3.5);
10
- expect(cmath.nextafter(1024, -Infinity)).toBe(1024 - Number.EPSILON * 1024/2);
11
- expect(cmath.nextafter(-0, 0)).toBe(0);
12
- expect(cmath.nextafter(0, -0)).toBe(-0);
13
- expect(cmath.nextafter(-0, -0)).toBe(-0);
14
- expect(cmath.nextafter(NaN, NaN)).toBe(NaN);
15
- expect(cmath.nextafter(NaN, 0)).toBe(NaN);
16
- expect(cmath.nextafter(0, NaN)).toBe(NaN);
17
- expect(cmath.nextafter(Infinity, Infinity)).toBe(Infinity);
18
- expect(cmath.nextafter(Infinity, -Infinity)).toBe(Number.MAX_VALUE);
19
- expect(cmath.nextafter(-Infinity, Infinity)).toBe(-Number.MAX_VALUE);
20
- expect(cmath.nextafter(-Infinity, -Infinity)).toBe(-Infinity);
21
- expect(cmath.nextafter(Number.MAX_VALUE, Infinity)).toBe(Infinity);
22
- expect(cmath.nextafter(-Number.MAX_VALUE, -Infinity)).toBe(-Infinity);
23
- expect(cmath.nextafter(Number.MIN_VALUE, -1)).toBe(0);
24
- expect(cmath.nextafter(-Number.MIN_VALUE, Infinity)).toBe(-0);
25
- expect(cmath.nextafter(Number.MIN_VALUE, -0)).toBe(0);
26
- expect(cmath.nextafter(Number.MIN_VALUE, 1)).toBe(Number.MIN_VALUE * 2);
27
- expect(cmath.nextafter(-Number.MIN_VALUE, -1)).toBe(-Number.MIN_VALUE * 2);
28
- });
29
-
30
- test("pow", () => {
31
- expect(cmath.pow(0, -3)).toBe(Infinity);
32
- expect(cmath.pow(-0, -3)).toBe(-Infinity);
33
- expect(cmath.pow(0, -4)).toBe(Infinity);
34
- expect(cmath.pow(-0, -4)).toBe(Infinity);
35
- expect(cmath.pow(0, -4.4)).toBe(Infinity);
36
- expect(cmath.pow(-0, -4.4)).toBe(Infinity);
37
- expect(cmath.pow(0, -Infinity)).toBe(Infinity);
38
- expect(cmath.pow(-0, -Infinity)).toBe(Infinity);
39
- expect(cmath.pow(NaN, 0)).toBe(1);
40
- expect(cmath.pow(1, NaN)).toBe(1);
41
- expect(cmath.pow(1, 45)).toBe(1);
42
- expect(cmath.pow(1, -654132432423)).toBe(1);
43
- expect(cmath.pow(-1, Infinity)).toBe(1);
44
- expect(cmath.pow(-1, -Infinity)).toBe(1);
45
- expect(cmath.pow(0, 555)).toBe(0);
46
- expect(cmath.pow(-0, 713737315)).toBe(-0);
47
- expect(cmath.pow(Infinity, -0.2)).toBe(0);
48
- expect(cmath.pow(Infinity, 3737315.5)).toBe(Infinity);
49
- expect(cmath.pow(-Infinity, 3737315)).toBe(-Infinity);
50
- expect(cmath.pow(-Infinity, 3737315.5)).toBe(Infinity);
51
- expect(cmath.pow(-3, 3)).toBe(-27);
52
-
53
- });
54
-
55
- test("signbit", () => {
56
- expect(cmath.signbit(-Infinity)).toBe(true);
57
- expect(cmath.signbit(-53245432534253)).toBe(true);
58
- expect(cmath.signbit(-0)).toBe(true);
59
- expect(cmath.signbit(0)).toBe(false);
60
- expect(cmath.signbit(98970789063)).toBe(false);
61
- expect(cmath.signbit(Infinity)).toBe(false);
62
- expect(cmath.signbit(NaN)).toBe(false);
63
-
64
- });
65
-
66
-
67
- test("frexp", () => {
68
- expect(cmath.frexp(1)).toStrictEqual([0.5, 1]);
69
- expect(cmath.frexp(1.5)).toStrictEqual([0.75, 1]);
70
- expect(cmath.frexp(3 * 2**500)).toStrictEqual([0.75, 502]);
71
- expect(cmath.frexp(-4)).toStrictEqual([-0.5, 3]);
72
- expect(cmath.frexp(Number.MAX_VALUE)).toStrictEqual([0.9999999999999999, 1024]);
73
- expect(cmath.frexp(Number.MIN_VALUE)).toStrictEqual([0.5, -1073]);
74
- expect(cmath.frexp(-Infinity)).toStrictEqual([-Infinity, 0]);
75
- expect(cmath.frexp(-0)).toStrictEqual([-0, 0]);
76
- expect(cmath.frexp(NaN)).toStrictEqual([NaN, 0]);
77
- });
78
-
79
-
80
- test("ldexp", () => {
81
- expect(cmath.ldexp(1.5, -1)).toBe(0.75);
82
- expect(cmath.ldexp(2**25, -3)).toBe(2**22);
83
- expect(cmath.ldexp(2**-1072, 1073)).toBe(2);
84
- expect(cmath.ldexp(2, 4)).toBe(2 ** 5);
85
- expect(cmath.ldexp(2, 5)).toBe(2 ** 6);
86
- expect(cmath.ldexp(NaN, -3)).toBe(NaN);
87
-
88
- expect(cmath.ldexp(NaN, NaN)).toBe(NaN);
89
- expect(cmath.ldexp(6, NaN)).toBe(NaN);
90
- expect(cmath.ldexp(Infinity, 43)).toBe(Infinity);
91
- });
92
-
93
-
94
- test("copysign", () => {
95
- expect(cmath.copysign(8, -4)).toBe(-8);
96
- expect(cmath.copysign(-8, -0.00000000000000000000001)).toBe(-8);
97
- expect(cmath.copysign(-Infinity, 0.00000000000000000000001)).toBe(Infinity);
98
-
99
- });
100
-
101
-
102
- test("abs and fabs", () => {
103
- for(let func of [cmath.abs, cmath.fabs]) {
104
- expect(func(123084109743)).toBe(123084109743);
105
- expect(func(-123084109743)).toBe(123084109743);
106
- expect(func(0)).toBe(0);
107
- }
108
- expect(cmath.fabs(12523423523523532432)).toBe(12523423523523532432);
109
- expect(cmath.fabs(-52523423523523532444432)).toBe(52523423523523532444432);
110
- expect(cmath.fabs(-0)).toBe(0);
111
- expect(cmath.fabs(-Infinity)).toBe(Infinity);
112
- expect(cmath.fabs(NaN)).toBe(NaN);
113
- });
114
-
115
-
116
- test("hypot", () => {
117
- expect(cmath.hypot(105, 100)).toBeCloseTo(145, 3);
118
- expect(cmath.hypot(-Infinity, 0)).toBe(Infinity);
119
- expect(cmath.hypot(0, -0.1451493619437592)).toBe(0.1451493619437592);
120
- expect(cmath.hypot(0, 0, -0.1451493619437592)).toBe(0.1451493619437592);
121
- expect(cmath.hypot(-3, -2, -1)).toBeCloseTo(3.741657386773941, 3);
122
- }, 1000);
123
-