math-f16round.js (3009B)
1 function fromConstant() { 2 // ToFloat16(ToDouble(constant)) is folded to ToFloat16(constant). 3 4 for (let i = 0; i < 100; ++i) { 5 assertEq(Math.f16round(0), 0); 6 assertEq(Math.f16round(0.1), 0.0999755859375); 7 assertEq(Math.f16round(0.5), 0.5); 8 assertEq(Math.f16round(1), 1); 9 assertEq(Math.f16round(2049), 2048); 10 assertEq(Math.f16round(65520), Infinity); 11 12 assertEq(Math.f16round(-0), -0); 13 assertEq(Math.f16round(-0.1), -0.0999755859375); 14 assertEq(Math.f16round(-0.5), -0.5); 15 assertEq(Math.f16round(-1), -1); 16 assertEq(Math.f16round(-2049), -2048); 17 assertEq(Math.f16round(-65520), -Infinity); 18 19 assertEq(Math.f16round(NaN), NaN); 20 assertEq(Math.f16round(Infinity), Infinity); 21 assertEq(Math.f16round(-Infinity), -Infinity); 22 23 assertEq(Math.f16round(0 / 0), NaN); 24 assertEq(Math.f16round(1 / 0), Infinity); 25 assertEq(Math.f16round(-1 / 0), -Infinity); 26 } 27 } 28 for (let i = 0; i < 2; ++i) fromConstant(); 29 30 function fromInt32() { 31 // ToFloat16(ToDouble(int32)) is folded to ToFloat16(int32). 32 33 // Int32 which are exactly representable as Float16. 34 for (let i = 0; i <= 2048; ++i) { 35 let i32 = i | 0; 36 assertEq(Math.f16round(i32), i32); 37 } 38 39 // Int32 larger than 2048 are inexact. 40 assertEq(Math.f16round(2049), 2048); 41 42 // Int32 larger than 65519 are not representable. 43 assertEq(Math.f16round(65519), 65504); 44 45 // Int32 which are too large for Float16. 46 for (let i = 0; i <= 100; ++i) { 47 let i32 = (i + 65520) | 0; 48 assertEq(Math.f16round(i32), Infinity); 49 } 50 } 51 for (let i = 0; i < 2; ++i) fromInt32(); 52 53 function fromFloat32() { 54 // ToFloat16(ToDouble(float32)) is folded to ToFloat16(float32). 55 56 // Float32 which are exactly representable as Float16. 57 for (let i = 0; i < 1024; ++i) { 58 let f32 = Math.fround(i + 0.5); 59 assertEq(Math.f16round(f32), f32); 60 } 61 62 // Float32 larger than 1023.5 are inexact. 63 assertEq(Math.f16round(1024.5), 1024); 64 65 // Float32 larger than 65519 are not representable. 66 assertEq(Math.f16round(65519.5), 65504); 67 68 // Float32 which are too large for Float16. 69 for (let i = 0; i <= 100; ++i) { 70 let f32 = Math.fround(i + 65520.5); 71 assertEq(Math.f16round(f32), Infinity); 72 } 73 } 74 for (let i = 0; i < 2; ++i) fromFloat32(); 75 76 function fromLoadFloat16() { 77 // ToFloat16(LoadFloat16(x)) is folded to LoadFloat16(x). 78 79 let f16 = new Float16Array([ 80 -Math.PI, 81 -65519, 82 -65520, 83 -2048, 84 -2049, 85 -0.5, 86 -0.1, 87 -0, 88 0, 89 0.1, 90 0.5, 91 Math.PI, 92 2048, 93 2049, 94 65519, 95 65520, 96 Infinity, 97 NaN, 98 ]); 99 100 let dv = new DataView(f16.buffer); 101 102 const nativeIsLittleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1; 103 104 for (let i = 0; i < 200; ++i) { 105 let idx = i % f16.length; 106 let x = f16[idx]; 107 let y = dv.getFloat16(idx * Float16Array.BYTES_PER_ELEMENT, nativeIsLittleEndian); 108 109 assertEq(x, y); 110 assertEq(Math.f16round(x), x); 111 assertEq(Math.f16round(y), y); 112 } 113 } 114 for (let i = 0; i < 2; ++i) fromLoadFloat16();