float-parsing.html (5901B)
1 <!-- 2 Copyright (c) 2019 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>Float parsing corner cases</title> 12 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 13 <script src="../../js/js-test-pre.js"></script> 14 <script src="../../js/webgl-test-utils.js"></script> 15 <script src="../../js/glsl-conformance-test.js"></script> 16 </head> 17 <body> 18 <div id="description"></div> 19 <div id="console"></div> 20 <script id="fshaderParsedFloatOverflowToInfinity" type="x-shader/x-fragment">#version 300 es 21 precision highp float; 22 out vec4 my_FragColor; 23 24 void main() 25 { 26 // Out-of-range floats should overflow to infinity 27 // GLSL ES 3.00.6 section 4.1.4 Floats: 28 // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity" 29 float correct = isinf(1.0e40) ? 1.0 : 0.0; 30 my_FragColor = vec4(0.0, correct, 0.0, 1.0); 31 } 32 </script> 33 <script id="fshaderParsedFloatUnderflowToZero" type="x-shader/x-fragment">#version 300 es 34 precision highp float; 35 out vec4 my_FragColor; 36 37 void main() 38 { 39 // GLSL ES 3.00.6 section 4.1.4 Floats: 40 // "A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero." 41 // 1.0e-50 is small enough that it can't even be stored as subnormal. 42 float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0; 43 my_FragColor = vec4(0.0, correct, 0.0, 1.0); 44 } 45 </script> 46 <script id="fshaderParsedFloatSmallMantissa" type="x-shader/x-fragment">#version 300 es 47 precision highp float; 48 out vec4 my_FragColor; 49 50 void main() 51 { 52 // GLSL ES 3.00.6 section 4.1.4 Floats: 53 // "There is no limit on the number of digits in any digit-sequence." 54 // The below float string has 100 zeros after the decimal point, but represents 1.0. 55 float x = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e101; 56 my_FragColor = vec4(0.0, x, 0.0, 1.0); 57 } 58 </script> 59 <script id="fshaderParsedFloatLargeMantissa" type="x-shader/x-fragment">#version 300 es 60 precision highp float; 61 out vec4 my_FragColor; 62 63 void main() 64 { 65 // GLSL ES 3.00.6 section 4.1.4 Floats: 66 // "There is no limit on the number of digits in any digit-sequence." 67 // The below float string has 100 zeros, but represents 1.0. 68 float x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0e-100; 69 my_FragColor = vec4(0.0, x, 0.0, 1.0); 70 } 71 </script> 72 <script id="fshaderParsedFloatExponentAboveMaxInt" type="x-shader/x-fragment">#version 300 es 73 precision highp float; 74 out vec4 my_FragColor; 75 76 void main() 77 { 78 // Out-of-range floats should overflow to infinity 79 // GLSL ES 3.00.6 section 4.1.4 Floats: 80 // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity" 81 float correct = isinf(1.0e2147483649) ? 1.0 : 0.0; 82 my_FragColor = vec4(0.0, correct, 0.0, 1.0); 83 } 84 </script> 85 <script id="fshaderNonConstFloatIsInfinity" type="x-shader/x-fragment">#version 300 es 86 precision highp float; 87 out vec4 my_FragColor; 88 89 uniform float u; // Assumed to have the default value 0.0 90 91 void main() 92 { 93 // Out-of-range floats should overflow to infinity 94 // GLSL ES 3.00.6 section 4.1.4 Floats: 95 // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity" 96 float f = 1.0e2048 - u; 97 float correct = (isinf(f) && f > 0.0) ? 1.0 : 0.0; 98 my_FragColor = vec4(0.0, correct, 0.0, 1.0); 99 } 100 </script> 101 <script id="fshaderNonConstFloatIsNegativeInfinity" type="x-shader/x-fragment">#version 300 es 102 precision highp float; 103 out vec4 my_FragColor; 104 105 uniform float u; // Assumed to have the default value 0.0 106 107 void main() 108 { 109 // Out-of-range floats should overflow to infinity 110 // GLSL ES 3.00.6 section 4.1.4 Floats: 111 // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity" 112 float f = -1.0e2048 + u; 113 float correct = (isinf(f) && f < 0.0) ? 1.0 : 0.0; 114 my_FragColor = vec4(0.0, correct, 0.0, 1.0); 115 } 116 </script> 117 <script type="text/javascript"> 118 "use strict"; 119 description(); 120 121 GLSLConformanceTester.runRenderTests([ 122 { 123 fShaderId: 'fshaderParsedFloatOverflowToInfinity', 124 fShaderSuccess: true, 125 linkSuccess: true, 126 passMsg: "Floats of too large magnitude should be converted infinity." 127 }, 128 { 129 fShaderId: 'fshaderParsedFloatUnderflowToZero', 130 fShaderSuccess: true, 131 linkSuccess: true, 132 passMsg: "Floats of too small magnitude should be converted to zero." 133 }, 134 { 135 fShaderId: 'fshaderParsedFloatSmallMantissa', 136 fShaderSuccess: true, 137 linkSuccess: true, 138 passMsg: "Number of digits in any digit-sequence is not limited - test with a small mantissa and large exponent." 139 }, 140 { 141 fShaderId: 'fshaderParsedFloatLargeMantissa', 142 fShaderSuccess: true, 143 linkSuccess: true, 144 passMsg: "Number of digits in any digit-sequence is not limited - test with a large mantissa and negative exponent." 145 }, 146 { 147 fShaderId: 'fshaderParsedFloatExponentAboveMaxInt', 148 fShaderSuccess: true, 149 linkSuccess: true, 150 passMsg: "Test that an exponent that slightly overflows signed 32-bit int range works." 151 }, 152 { 153 fShaderId: 'fshaderNonConstFloatIsInfinity', 154 fShaderSuccess: true, 155 linkSuccess: true, 156 passMsg: "Test that a non-constant float that has infinity as a value is processed correctly by isinf()." 157 }, 158 { 159 fShaderId: 'fshaderNonConstFloatIsNegativeInfinity', 160 fShaderSuccess: true, 161 linkSuccess: true, 162 passMsg: "Test that a non-constant float that has negative infinity as a value is processed correctly by isinf()." 163 } 164 ], 2); 165 </script> 166 </body> 167 </html>