Update changelog
[pkg-ocaml-js-of-ocaml.git] / runtime / ieee_754.js
blob5278d9e8da2da7bcbac8dbf3edfb0e2ffd78cfb7
1 // Js_of_ocaml runtime support
2 // http://www.ocsigen.org/js_of_ocaml/
3 // Copyright (C) 2010 Jérôme Vouillon
4 // Laboratoire PPS - CNRS Université Paris Diderot
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation, with linking exception;
9 // either version 2.1 of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 //Provides: caml_int64_bits_of_float const
21 function caml_int64_bits_of_float (x) {
22 if (!isFinite(x)) {
23 if (isNaN(x)) return [255, 1, 0, 0xfff0];
24 return (x > 0)?[255,0,0,0x7ff0]:[255,0,0,0xfff0];
26 var sign = (x>=0)?0:0x8000;
27 if (sign) x = -x;
28 var exp = Math.floor(Math.LOG2E*Math.log(x)) + 1023;
29 if (exp <= 0) {
30 exp = 0;
31 x /= Math.pow(2,-1026);
32 } else {
33 x /= Math.pow(2,exp-1027);
34 if (x < 16) { x *= 2; exp -=1; }
35 if (exp == 0) { x /= 2; }
37 var k = Math.pow(2,24);
38 var r3 = x|0;
39 x = (x - r3) * k;
40 var r2 = x|0;
41 x = (x - r2) * k;
42 var r1 = x|0;
43 r3 = (r3 &0xf) | sign | exp << 4;
44 return [255, r1, r2, r3];
46 //Provides: caml_int64_float_of_bits const
47 function caml_int64_float_of_bits (x) {
48 var exp = (x[3] & 0x7fff) >> 4;
49 if (exp == 2047) {
50 if ((x[1]|x[2]|(x[3]&0xf)) == 0)
51 return (x[3] & 0x8000)?(-Infinity):Infinity;
52 else
53 return NaN;
55 var k = Math.pow(2,-24);
56 var res = (x[1]*k+x[2])*k+(x[3]&0xf);
57 if (exp > 0) {
58 res += 16
59 res *= Math.pow(2,exp-1027);
60 } else
61 res *= Math.pow(2,-1026);
62 if (x[3] & 0x8000) res = - res;
63 return res;
65 //Provides: caml_classify_float const
66 function caml_classify_float (x) {
67 if (isFinite (x)) {
68 if (Math.abs(x) >= 2.2250738585072014e-308) return 0;
69 if (x != 0) return 1;
70 return 2;
72 return isNaN(x)?4:3;
74 //Provides: caml_modf_float const
75 function caml_modf_float (x) {
76 if (isFinite (x)) {
77 var neg = (1/x) < 0;
78 x = Math.abs(x);
79 var i = Math.floor (x);
80 var f = x - i;
81 if (neg) { i = -i; f = -f; }
82 return [0, f, i];
84 if (isNaN (x)) return [0, NaN, NaN];
85 return [0, 1/x, x];
87 //Provides: caml_ldexp_float const
88 function caml_ldexp_float (x,exp) {
89 exp |= 0;
90 if (exp > 1023) {
91 exp -= 1023;
92 x *= Math.pow(2, 1023);
93 if (exp > 1023) { // in case x is subnormal
94 exp -= 1023;
95 x *= Math.pow(2, 1023);
98 if (exp < -1023) {
99 exp += 1023;
100 x *= Math.pow(2, -1023);
102 x *= Math.pow(2, exp);
103 return x;
105 //Provides: caml_frexp_float const
106 function caml_frexp_float (x) {
107 if ((x == 0) || !isFinite(x)) return [0, x, 0];
108 var neg = x < 0;
109 if (neg) x = - x;
110 var exp = Math.floor(Math.LOG2E*Math.log(x)) + 1;
111 x *= Math.pow(2,-exp);
112 if (x < 0.5) { x *= 2; exp -= 1; }
113 if (neg) x = - x;
114 return [0, x, exp];
117 //Provides: caml_float_compare const
118 function caml_float_compare (x, y) {
119 if (x === y) return 0;
120 if (x < y) return -1;
121 if (x > y) return 1;
122 if (x === x) return 1;
123 if (y === y) return -1;
124 return 0;
127 // FIX: these four functions only give approximate results.
128 //Provides: caml_log10_float const
129 function caml_log10_float (x) { return Math.LOG10E * Math.log(x); }
130 //Provides: caml_cosh_float const
131 function caml_cosh_float (x) { return (Math.exp(x) + Math.exp(-x)) / 2; }
132 //Provides: caml_sinh_float const
133 function caml_sinh_float (x) { return (Math.exp(x) - Math.exp(-x)) / 2; }
134 //Provides: caml_tanh_float const
135 function caml_tanh_float (x) {
136 var y = Math.exp(x), z = Math.exp(-x);
137 return (y + z) / (y - z);