@@ -24,114 +24,23 @@ var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
24
24
var SIGN_MASK = require ( '@stdlib/constants/float32/sign-mask' ) ;
25
25
var toWordf = require ( '@stdlib/number/float32/base/to-word' ) ;
26
26
var abs = require ( '@stdlib/math/base/special/abs' ) ;
27
- var Uint32Array = require ( '@stdlib/array/uint32' ) ;
28
-
29
-
30
- // VARIABLES //
31
-
32
- var WX = new Uint32Array ( 2 ) ; // WARNING: not thread safe
33
- var WY = new Uint32Array ( 2 ) ;
34
- var WZ = new Uint32Array ( 2 ) ;
35
-
36
- // 2^32:
37
- var TWO_32 = 4294967296 ;
38
27
39
28
40
29
// FUNCTIONS //
41
30
42
31
/**
43
- * Converts the high and low words of a single-precision floating-point number to a lexicographically ordered integer.
44
- *
45
- * ## Notes
46
- *
47
- * - This function mutates the input array.
32
+ * Converts an unsigned 32-bit integer corresponding to the IEEE 754 binary representation of a single-precision floating-point number to a lexicographically ordered integer.
48
33
*
49
34
* @private
50
- * @param {Array<integer> } words - high and low words
51
- * @returns {Array< integer> } input array
35
+ * @param {unsigned32 } word - unsigned 32-bit integer
36
+ * @returns {integer } lexicographically ordered integer
52
37
*/
53
38
function monotoneKey ( word ) {
54
39
if ( word & SIGN_MASK ) { // x < 0
55
- return ( ~ word + 1 ) >>> 0 ; // maps -∞ to 0
56
- }
57
- return ( word | SIGN_MASK ) >>> 0 ; // maps +∞ to 2^32-1
58
- }
59
-
60
- /**
61
- * Perform two's-complement negation.
62
- *
63
- * ## Notes
64
- *
65
- * - This function mutates the input array.
66
- *
67
- * @private
68
- * @param {Array<integer> } words - high and low words
69
- * @returns {Array<integer> } input array
70
- */
71
- function negate ( words ) {
72
- words [ 0 ] = ~ words [ 0 ] ;
73
- words [ 1 ] = ~ words [ 1 ] ;
74
- words [ 1 ] += 1 ;
75
-
76
- // Handle the carry into the high word...
77
- if ( words [ 1 ] === 0 ) {
78
- words [ 0 ] += 1 ;
79
- }
80
- return words ;
81
- }
82
-
83
- /**
84
- * Returns the ordering of two single-precision floating-point numbers according to their lexicographically ordered high and low words.
85
- *
86
- * @private
87
- * @param {Array<integer> } wa - high and low words for first value
88
- * @param {Array<integer> } wb - high and low words for second value
89
- * @returns {integer } relative ordering
90
- */
91
- function compare ( wa , wb ) {
92
- if ( wa [ 0 ] > wb [ 0 ] ) {
93
- return 1 ;
94
- }
95
- if ( wa [ 0 ] < wb [ 0 ] ) {
96
- return - 1 ;
97
- }
98
- if ( wa [ 1 ] > wb [ 1 ] ) {
99
- return 1 ;
100
- }
101
- if ( wa [ 1 ] < wb [ 1 ] ) {
102
- return - 1 ;
103
- }
104
- return 0 ;
105
- }
106
-
107
- /**
108
- * Performs double-word subtraction.
109
- *
110
- * @private
111
- * @param {Array<integer> } wa - high and low words for first value
112
- * @param {Array<integer> } wb - high and low words for second value
113
- * @param {Array<integer> } wc - output array
114
- * @returns {Array<integer> } output array
115
- */
116
- function subtract ( wa , wb , wc ) {
117
- var ha ;
118
- var hb ;
119
- var la ;
120
- var lb ;
121
-
122
- ha = wa [ 0 ] ;
123
- la = wa [ 1 ] ;
124
- hb = wb [ 0 ] ;
125
- lb = wb [ 1 ] ;
126
-
127
- if ( la >= lb ) {
128
- wc [ 0 ] = ha - hb ;
129
- wc [ 1 ] = la - lb ;
130
- } else {
131
- wc [ 0 ] = ( ha - hb - 1 ) ; // wrap
132
- wc [ 1 ] = ( la + TWO_32 ) - lb ; // borrow
40
+ return ( ~ word + 1 ) ;
133
41
}
134
- return wc ;
42
+ // x >= 0
43
+ return ( word | SIGN_MASK ) >>> 0 ; // push +0 to just above -0
135
44
}
136
45
137
46
@@ -171,23 +80,21 @@ function subtract( wa, wb, wc ) {
171
80
* // returns NaN
172
81
*/
173
82
function ulpdiff ( x , y ) {
174
- var ord ;
175
83
var wx ;
176
84
var wy ;
177
- var wz ;
178
85
179
86
if ( isnanf ( x ) || isnanf ( y ) ) {
180
87
return NaN ;
181
88
}
182
- // Convert input values to high and low words :
89
+ // Convert input values to unsigned 32-bit integers corresponding to the IEEE 754 binary representation of single-precision floating-point numbers :
183
90
wx = toWordf ( x ) ;
184
91
wy = toWordf ( y ) ;
185
92
186
- // Convert the values to lexicographically order integers:
93
+ // Convert the words to lexicographically order integers:
187
94
wx = monotoneKey ( wx ) ;
188
95
wy = monotoneKey ( wy ) ;
189
96
190
- // Return a double as a result, which is fine for ≤2^53 ulps :
97
+ // Return a double as a result, which can exactly represent the ULP difference for all representable single-precision floating-point numbers :
191
98
return abs ( wx - wy ) ;
192
99
}
193
100
0 commit comments