Skip to content

Commit 02f1bf3

Browse files
committed
Runtime: simplify logic converting between floats and bits
1 parent 1fa0eca commit 02f1bf3

File tree

4 files changed

+30
-86
lines changed

4 files changed

+30
-86
lines changed

compiler/lib/reserved.ml

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ let provided =
144144
; "require" (* only available in node *)
145145
; "Symbol"
146146
; "ArrayBuffer"
147+
; "DataView"
147148
; "Float32Array"
148149
; "Float64Array"
149150
; "Int16Array"

compiler/tests-jsoo/test_marshal.ml

+5-3
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,9 @@ let%expect_test "test float" =
157157
Printf.printf "%f" (Marshal.from_string r1 0);
158158
[%expect
159159
{|
160-
"\132\149\166\190\000\000\000\t\000\000\000\000\000\000\000\003\000\000\000\002\012\031\133\235Q\184\030\t@"
161-
3.140000 |}];
160+
"\132\149\166\190\000\000\000\t\000\000\000\000\000\000\000\003\000\000\000\002\012\031\133\235Q\184\030\t@"
161+
3.140000
162+
|}];
162163
let r2 = Marshal.to_string obj [] in
163164
Printf.printf "%S\n" r2;
164165
let a, b, c, d =
@@ -170,7 +171,8 @@ let%expect_test "test float" =
170171
[%expect
171172
{|
172173
"\132\149\166\190\000\000\000\017\000\000\000\004\000\000\000\012\000\000\000\011\160\160\012\031\133\235Q\184\030\t@\004\001\160\004\003@"
173-
3.140000 3.140000 3.140000 3.140000 |}]
174+
3.140000 3.140000 3.140000 3.140000
175+
|}]
174176

175177
let%expect_test "test input with offset" =
176178
let s = 3.14 in

compiler/tests-ocaml/lib-hashtbl/hfun_js.expected

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
-0.0 07be548a
1313
+infty 23ea56fb
1414
-infty 059f7872
15-
NaN 3228858d
16-
NaN#2 3228858d
17-
NaN#3 3228858d
15+
NaN 23498e72
16+
NaN#2 23498e72
17+
NaN#3 23498e72
1818
-- Native integers:
1919
0 07be548a
2020
-1 3653e015

runtime/js/ieee_754.js

+21-80
Original file line numberDiff line numberDiff line change
@@ -17,74 +17,27 @@
1717
// along with this program; if not, write to the Free Software
1818
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1919

20-
//Provides: jsoo_floor_log2
21-
var log2_ok = Math.log2 && Math.log2(1.1235582092889474e307) === 1020;
22-
function jsoo_floor_log2(x) {
23-
if (log2_ok) return Math.floor(Math.log2(x));
24-
var i = 0;
25-
if (x === 0) return Number.NEGATIVE_INFINITY;
26-
if (x >= 1) {
27-
while (x >= 2) {
28-
x /= 2;
29-
i++;
30-
}
31-
} else {
32-
while (x < 1) {
33-
x *= 2;
34-
i--;
35-
}
36-
}
37-
return i;
38-
}
20+
//Provides: jsoo_dataview
21+
var jsoo_dataview = new DataView(new ArrayBuffer(8));
3922

4023
//Provides: caml_int64_bits_of_float const
41-
//Requires: jsoo_floor_log2, caml_int64_create_lo_mi_hi
24+
//Requires: caml_int64_create_lo_mi_hi
25+
//Requires: jsoo_dataview
4226
function caml_int64_bits_of_float(x) {
43-
if (!Number.isFinite(x)) {
44-
if (Number.isNaN(x)) return caml_int64_create_lo_mi_hi(1, 0, 0x7ff0);
45-
if (x > 0) return caml_int64_create_lo_mi_hi(0, 0, 0x7ff0);
46-
else return caml_int64_create_lo_mi_hi(0, 0, 0xfff0);
47-
}
48-
var sign =
49-
x === 0 && 1 / x === Number.NEGATIVE_INFINITY
50-
? 0x8000
51-
: x >= 0
52-
? 0
53-
: 0x8000;
54-
if (sign) x = -x;
55-
// Int64.bits_of_float 1.1235582092889474E+307 = 0x7fb0000000000000L
56-
// using Math.LOG2E*Math.log(x) in place of Math.log2 result in precision lost
57-
var exp = jsoo_floor_log2(x) + 1023;
58-
if (exp <= 0) {
59-
exp = 0;
60-
x /= Math.pow(2, -1026);
61-
} else {
62-
x /= Math.pow(2, exp - 1027);
63-
if (x < 16) {
64-
x *= 2;
65-
exp -= 1;
66-
}
67-
if (exp === 0) {
68-
x /= 2;
69-
}
70-
}
71-
var k = Math.pow(2, 24);
72-
var r3 = x | 0;
73-
x = (x - r3) * k;
74-
var r2 = x | 0;
75-
x = (x - r2) * k;
76-
var r1 = x | 0;
77-
r3 = (r3 & 0xf) | sign | (exp << 4);
27+
jsoo_dataview.setFloat64(0, x, true);
28+
var lo32 = jsoo_dataview.getUint32(0, true);
29+
var hi32 = jsoo_dataview.getUint32(4, true);
30+
var r1 = lo32 & 0xffffff;
31+
var r2 = (lo32 >>> 24) | ((hi32 << 8) & 0xffffff);
32+
var r3 = (hi32 >>> 16) & 0xffff;
7833
return caml_int64_create_lo_mi_hi(r1, r2, r3);
7934
}
8035

8136
//Provides: caml_int32_bits_of_float const
82-
//Requires: jsoo_floor_log2
37+
//Requires: jsoo_dataview
8338
function caml_int32_bits_of_float(x) {
84-
var float32a = new Float32Array(1);
85-
float32a[0] = x;
86-
var int32a = new Int32Array(float32a.buffer);
87-
return int32a[0] | 0;
39+
jsoo_dataview.setFloat32(0, x, true);
40+
return jsoo_dataview.getUint32(0, true) | 0;
8841
}
8942

9043
//FP literals can be written using the hexadecimal
@@ -150,24 +103,14 @@ function caml_hexstring_of_float(x, prec, style) {
150103
}
151104

152105
//Provides: caml_int64_float_of_bits const
106+
//Requires: jsoo_dataview
153107
function caml_int64_float_of_bits(x) {
154108
var lo = x.lo;
155109
var mi = x.mi;
156110
var hi = x.hi;
157-
var exp = (hi & 0x7fff) >> 4;
158-
if (exp === 2047) {
159-
if ((lo | mi | (hi & 0xf)) === 0)
160-
return hi & 0x8000 ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY;
161-
else return Number.NaN;
162-
}
163-
var k = Math.pow(2, -24);
164-
var res = (lo * k + mi) * k + (hi & 0xf);
165-
if (exp > 0) {
166-
res += 16;
167-
res *= Math.pow(2, exp - 1027);
168-
} else res *= Math.pow(2, -1026);
169-
if (hi & 0x8000) res = -res;
170-
return res;
111+
jsoo_dataview.setUint32(0, lo | (mi << 24), true);
112+
jsoo_dataview.setUint32(4, (mi >>> 8) | (hi << 16), true);
113+
return jsoo_dataview.getFloat64(0, true);
171114
}
172115

173116
//Provides: caml_nextafter_float const
@@ -192,11 +135,10 @@ function caml_trunc_float(x) {
192135
}
193136

194137
//Provides: caml_int32_float_of_bits const
138+
//Requires: jsoo_dataview
195139
function caml_int32_float_of_bits(x) {
196-
var int32a = new Int32Array(1);
197-
int32a[0] = x;
198-
var float32a = new Float32Array(int32a.buffer);
199-
return float32a[0];
140+
jsoo_dataview.setUint32(0, x, true);
141+
return jsoo_dataview.getFloat32(0, true);
200142
}
201143

202144
//Provides: caml_classify_float const
@@ -244,12 +186,11 @@ function caml_ldexp_float(x, exp) {
244186
return x;
245187
}
246188
//Provides: caml_frexp_float const
247-
//Requires: jsoo_floor_log2
248189
function caml_frexp_float(x) {
249190
if (x === 0 || !Number.isFinite(x)) return [0, x, 0];
250191
var neg = x < 0;
251192
if (neg) x = -x;
252-
var exp = Math.max(-1023, jsoo_floor_log2(x) + 1);
193+
var exp = Math.max(-1023, Math.floor(Math.log2(x)) + 1);
253194
x *= Math.pow(2, -exp);
254195
while (x < 0.5) {
255196
x *= 2;

0 commit comments

Comments
 (0)