@lvlte/ulp 1.1.1 → 1.2.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/dist/cjs/index.d.ts +20 -2
- package/dist/cjs/index.js +23 -0
- package/dist/index.d.ts +20 -2
- package/dist/index.js +21 -0
- package/package.json +7 -6
- package/readme.md +39 -15
package/dist/cjs/index.d.ts
CHANGED
|
@@ -20,7 +20,25 @@ export declare const ulp: typeof eps;
|
|
|
20
20
|
* Exponent of a normalized floating-point number x.
|
|
21
21
|
*
|
|
22
22
|
* @param x The input number
|
|
23
|
-
* @returns The largest integer `y` such that `2^y ≤ |x
|
|
24
|
-
*
|
|
23
|
+
* @returns The largest integer `y` such that `2^y ≤ |x|`. If `x` is not a
|
|
24
|
+
* finite number or equals ±0, returns `NaN`.
|
|
25
25
|
*/
|
|
26
26
|
export declare function exponent(x: number): number;
|
|
27
|
+
/**
|
|
28
|
+
* Return the smallest representable floating-point number that comes after `x`
|
|
29
|
+
* on the float64 number line (towards +∞).
|
|
30
|
+
*
|
|
31
|
+
* @param x The input number
|
|
32
|
+
* @returns The smallest floating-point number `y` such that `y > x`. If `x` is
|
|
33
|
+
* `±Infinity` or `NaN`, returns `x`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function nextFloat(x: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Return the largest representable floating-point number that comes before `x`
|
|
38
|
+
* on the float64 number line (towards -∞).
|
|
39
|
+
*
|
|
40
|
+
* @param x The input number
|
|
41
|
+
* @returns The largest floating-point number `y` such that `y < x`. If `x` is
|
|
42
|
+
* `±Infinity` or `NaN`, returns `x`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function prevFloat(x: number): number;
|
package/dist/cjs/index.js
CHANGED
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ulp = exports.FLOAT64_MIN = void 0;
|
|
4
4
|
exports.eps = eps;
|
|
5
5
|
exports.exponent = exponent;
|
|
6
|
+
exports.nextFloat = nextFloat;
|
|
7
|
+
exports.prevFloat = prevFloat;
|
|
6
8
|
exports.FLOAT64_MIN = Math.pow(2, -1022);
|
|
7
9
|
function eps(x = 1) {
|
|
8
10
|
if (Number.isFinite(x)) {
|
|
@@ -25,3 +27,24 @@ function _exponent(x) {
|
|
|
25
27
|
const s = x.toString(2);
|
|
26
28
|
return x < 1 ? -(s.split('1', 1)[0].length - 1) : s.split('.', 1)[0].length - 1;
|
|
27
29
|
}
|
|
30
|
+
function nextFloat(x) {
|
|
31
|
+
switch (x) {
|
|
32
|
+
case -Infinity:
|
|
33
|
+
return -Number.MAX_VALUE;
|
|
34
|
+
case Infinity:
|
|
35
|
+
case Number.MAX_VALUE:
|
|
36
|
+
return Infinity;
|
|
37
|
+
case -Number.MIN_VALUE:
|
|
38
|
+
return -0;
|
|
39
|
+
default:
|
|
40
|
+
if (!Number.isFinite(x)) {
|
|
41
|
+
return NaN;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const e = eps(x);
|
|
45
|
+
const y = x + e / 2;
|
|
46
|
+
return y > x ? y : x + e;
|
|
47
|
+
}
|
|
48
|
+
function prevFloat(x) {
|
|
49
|
+
return typeof x === 'number' ? -nextFloat(-x) : NaN;
|
|
50
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,25 @@ export declare const ulp: typeof eps;
|
|
|
20
20
|
* Exponent of a normalized floating-point number x.
|
|
21
21
|
*
|
|
22
22
|
* @param x The input number
|
|
23
|
-
* @returns The largest integer `y` such that `2^y ≤ |x
|
|
24
|
-
*
|
|
23
|
+
* @returns The largest integer `y` such that `2^y ≤ |x|`. If `x` is not a
|
|
24
|
+
* finite number or equals ±0, returns `NaN`.
|
|
25
25
|
*/
|
|
26
26
|
export declare function exponent(x: number): number;
|
|
27
|
+
/**
|
|
28
|
+
* Return the smallest representable floating-point number that comes after `x`
|
|
29
|
+
* on the float64 number line (towards +∞).
|
|
30
|
+
*
|
|
31
|
+
* @param x The input number
|
|
32
|
+
* @returns The smallest floating-point number `y` such that `y > x`. If `x` is
|
|
33
|
+
* `±Infinity` or `NaN`, returns `x`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function nextFloat(x: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Return the largest representable floating-point number that comes before `x`
|
|
38
|
+
* on the float64 number line (towards -∞).
|
|
39
|
+
*
|
|
40
|
+
* @param x The input number
|
|
41
|
+
* @returns The largest floating-point number `y` such that `y < x`. If `x` is
|
|
42
|
+
* `±Infinity` or `NaN`, returns `x`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function prevFloat(x: number): number;
|
package/dist/index.js
CHANGED
|
@@ -20,3 +20,24 @@ function _exponent(x) {
|
|
|
20
20
|
const s = x.toString(2);
|
|
21
21
|
return x < 1 ? -(s.split('1', 1)[0].length - 1) : s.split('.', 1)[0].length - 1;
|
|
22
22
|
}
|
|
23
|
+
export function nextFloat(x) {
|
|
24
|
+
switch (x) {
|
|
25
|
+
case -Infinity:
|
|
26
|
+
return -Number.MAX_VALUE;
|
|
27
|
+
case Infinity:
|
|
28
|
+
case Number.MAX_VALUE:
|
|
29
|
+
return Infinity;
|
|
30
|
+
case -Number.MIN_VALUE:
|
|
31
|
+
return -0;
|
|
32
|
+
default:
|
|
33
|
+
if (!Number.isFinite(x)) {
|
|
34
|
+
return NaN;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const e = eps(x);
|
|
38
|
+
const y = x + e / 2;
|
|
39
|
+
return y > x ? y : x + e;
|
|
40
|
+
}
|
|
41
|
+
export function prevFloat(x) {
|
|
42
|
+
return typeof x === 'number' ? -nextFloat(-x) : NaN;
|
|
43
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvlte/ulp",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Compute the
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "Compute the ULP of a given number / Get the closest representable number that comes before/after it on the float64 number line",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eric Lavault <lvlte.code@gmail.com>",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/lvlte/ulp"
|
|
9
|
+
"url": "git+https://github.com/lvlte/ulp.git"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"main": "./dist/cjs/index.js",
|
|
@@ -38,17 +38,18 @@
|
|
|
38
38
|
"keywords": [
|
|
39
39
|
"number",
|
|
40
40
|
"epsilon",
|
|
41
|
-
"function",
|
|
42
41
|
"precision",
|
|
43
42
|
"eps",
|
|
44
43
|
"ulp",
|
|
44
|
+
"nextFloat",
|
|
45
|
+
"prevFloat",
|
|
46
|
+
"next",
|
|
47
|
+
"previous",
|
|
45
48
|
"float",
|
|
46
49
|
"float64",
|
|
47
50
|
"IEEE-754",
|
|
48
51
|
"rounding",
|
|
49
52
|
"tolerance",
|
|
50
|
-
"compare",
|
|
51
|
-
"equal",
|
|
52
53
|
"ULP"
|
|
53
54
|
],
|
|
54
55
|
"devDependencies": {
|
package/readme.md
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# ulp (epsilon function)
|
|
2
2
|
|
|
3
|
-
> Compute the [
|
|
4
|
-
of a given IEEE-754 64-bit number
|
|
3
|
+
> Compute the [ULP](https://en.wikipedia.org/wiki/Unit_in_the_last_place)
|
|
4
|
+
of a given IEEE-754 64-bit number: `eps(x)` (alias: `ulp(x)`).<br>
|
|
5
|
+
> Get the closest representable number that comes before/after it on the float64
|
|
6
|
+
number line: `nextFloat(x)`, `prevFloat(x)`.
|
|
7
|
+
|
|
5
8
|
|
|
6
9
|
## Install
|
|
7
10
|
|
|
@@ -11,30 +14,51 @@ npm install @lvlte/ulp
|
|
|
11
14
|
|
|
12
15
|
## Usage
|
|
13
16
|
|
|
17
|
+
### Import
|
|
18
|
+
|
|
14
19
|
```js
|
|
15
20
|
// ESM
|
|
16
|
-
import { eps } from '@lvlte/ulp';
|
|
21
|
+
import { eps, nextFloat, prevFloat } from '@lvlte/ulp';
|
|
17
22
|
```
|
|
18
23
|
```js
|
|
19
24
|
// CJS
|
|
20
|
-
const { eps } = require('@lvlte/ulp');
|
|
25
|
+
const { eps, nextFloat, prevFloat } = require('@lvlte/ulp');
|
|
21
26
|
```
|
|
27
|
+
|
|
28
|
+
### eps(x) / ulp(x) (alias)
|
|
29
|
+
```js
|
|
30
|
+
console.log( eps() ); // 2.220446049250313e-16
|
|
31
|
+
console.log( eps() === eps(1) ); // true
|
|
32
|
+
console.log( eps() === Number.EPSILON ); // true
|
|
33
|
+
|
|
34
|
+
console.log( eps(Number.MAX_SAFE_INTEGER) ); // 1
|
|
35
|
+
console.log( eps(Number.MAX_SAFE_INTEGER + 1) ); // 2
|
|
36
|
+
|
|
37
|
+
console.log( eps(0) ); // 5e-324
|
|
38
|
+
console.log( eps(0) === Number.MIN_VALUE ); // true
|
|
39
|
+
|
|
40
|
+
console.log( eps(Infinity) ); // NaN
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### nextFloat(x) / prevFloat(x)
|
|
22
44
|
```js
|
|
23
|
-
console.log(
|
|
24
|
-
console.log(
|
|
25
|
-
console.log(eps() === Number.EPSILON); // true
|
|
45
|
+
console.log( nextFloat(0) ); // 5e-324
|
|
46
|
+
console.log( nextFloat(0) === Number.MIN_VALUE ); // true
|
|
26
47
|
|
|
27
|
-
console.log(
|
|
28
|
-
console.log(
|
|
48
|
+
console.log( nextFloat(1) ); // 1.0000000000000002
|
|
49
|
+
console.log( nextFloat(1) === 1 + eps(1) ); // true
|
|
29
50
|
|
|
30
|
-
console.log(
|
|
31
|
-
console.log(
|
|
51
|
+
console.log( nextFloat(Number.MAX_SAFE_INTEGER) ); // 9007199254740992
|
|
52
|
+
console.log( nextFloat(9007199254740992) ); // 9007199254740994
|
|
53
|
+
console.log( nextFloat(Number.MAX_VALUE) ); // Infinity
|
|
32
54
|
|
|
33
|
-
console.log(
|
|
55
|
+
console.log( prevFloat(0) ); // -5e-324
|
|
56
|
+
console.log( prevFloat(1) ); // 0.9999999999999999
|
|
57
|
+
console.log( prevFloat(9007199254740992) ); // 9007199254740991
|
|
58
|
+
console.log( prevFloat(Infinity) ); // 1.7976931348623157e+308
|
|
34
59
|
```
|
|
35
60
|
|
|
36
61
|
## Use case
|
|
37
62
|
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- Get the next/previous float on the float64 number line.
|
|
63
|
+
- Use the proper tolerance to check whether two floating-point numbers should be considered equal.
|
|
64
|
+
- Use the proper tolerance to approximate a floating-point number as a rational number.
|