1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
// Some tests regarding conversion to Float32
assertEq(Math.fround(), NaN);
// Special values
assertEq(Math.fround(NaN), NaN);
assertEq(Math.fround(-Infinity), -Infinity);
assertEq(Math.fround(Infinity), Infinity);
assertEq(Math.fround(-0), -0);
assertEq(Math.fround(+0), +0);
// Polyfill function for Float32 conversion
var toFloat32 = (function() {
var f32 = new Float32Array(1);
function f(x) {
f32[0] = x;
return f32[0];
}
return f;
})();
// A test on a certain range of numbers, including big numbers, so that
// we get a loss in precision for some of them.
for (var i = 0; i < 64; ++i) {
var p = Math.pow(2, i) + 1;
assertEq(Math.fround(p), toFloat32(p));
assertEq(Math.fround(-p), toFloat32(-p));
}
/********************************************
/* Tests on maximal Float32 / Double values *
/*******************************************/
function maxValue(exponentWidth, significandWidth) {
var n = 0;
var maxExp = Math.pow(2, exponentWidth - 1) - 1;
for (var i = significandWidth; i >= 0; i--)
n += Math.pow(2, maxExp - i);
return n;
}
var DBL_MAX = maxValue(11, 52);
assertEq(DBL_MAX, Number.MAX_VALUE); // sanity check
// Finite as a double, too big for a float
assertEq(Math.fround(DBL_MAX), Infinity);
var FLT_MAX = maxValue(8, 23);
assertEq(Math.fround(FLT_MAX), FLT_MAX);
assertEq(Math.fround(FLT_MAX + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 2)), FLT_MAX); // round-nearest rounds down to FLT_MAX
assertEq(Math.fround(FLT_MAX + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 1)), Infinity); // no longer rounds down to FLT_MAX
/*********************************************************
/******* Tests on denormalizations and roundings *********
/********************************************************/
function minValue(exponentWidth, significandWidth) {
return Math.pow(2, -(Math.pow(2, exponentWidth - 1) - 2) - significandWidth);
}
var DBL_MIN = Math.pow(2, -1074);
assertEq(DBL_MIN, Number.MIN_VALUE); // sanity check
// Too small for a float
assertEq(Math.fround(DBL_MIN), 0);
var FLT_MIN = minValue(8, 23);
assertEq(Math.fround(FLT_MIN), FLT_MIN);
assertEq(Math.fround(FLT_MIN / 2), 0); // halfway, round-nearest rounds down to 0 (even)
assertEq(Math.fround(FLT_MIN / 2 + Math.pow(2, -202)), FLT_MIN); // first double > FLT_MIN / 2, rounds up to FLT_MIN
assertEq(Math.fround(-FLT_MIN), -FLT_MIN);
assertEq(Math.fround(-FLT_MIN / 2), -0); // halfway, round-nearest rounds up to -0 (even)
assertEq(Math.fround(-FLT_MIN / 2 - Math.pow(2, -202)), -FLT_MIN); // first double < -FLT_MIN / 2, rounds down to -FLT_MIN
reportCompare(0, 0, "ok");
|