shithub: rgbds

Download patch

ref: 8553b61a946527d12f2af7b75b1a7c66b8044ca1
parent: ab12c474d27291fe69b25e68d00184b05a601926
author: Rangi <35663410+Rangi42@users.noreply.github.com>
date: Sun Oct 2 01:08:38 EDT 2022

Fixed-point values can use all 32-Q magnitude bits (#1085)


--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -1179,7 +1179,7 @@
 		precision = fixPrecision;
 	}
 
-	if (integer >= ((uint64_t)1 << precision))
+	if (integer >= ((uint64_t)1 << (32 - precision)))
 		warning(WARNING_LARGE_CONSTANT, "Magnitude of fixed-point constant is too large\n");
 
 	// Cast to unsigned avoids undefined overflow behavior
--- a/test/asm/fixed-point-magnitude.asm
+++ b/test/asm/fixed-point-magnitude.asm
@@ -1,13 +1,19 @@
-OPT Q.4
-println 1.0
-println -1.0
-println 0.0625
-println -0.0625
-println 7.25
-println -7.25
-println 12.25
-println -12.25
-println 15.9375
-println -15.9375
-println 20.0
-println -20.0
+for precision, 1, 32
+	opt Q{d:precision}
+	def magnitude = 32 - precision
+
+	def maxInt = 1 << magnitude - 1
+	redef defMaxValue equs "def maxValue = {d:maxInt}.0"
+	{defMaxValue}
+	println "Q.{2d:precision}: max ok  = 1 << {2d:magnitude} - 1  = {11d:maxInt}.0 = {#09x:maxValue}"
+
+	def minBadInt = maxInt + 1
+	redef defMinBadValue equs "def minBadValue = {d:minBadInt}.0"
+	{defMinBadValue}
+	println "Q.{2d:precision}: min bad = 1 << {2d:magnitude}      = {11d:minBadInt}.0 = {#09x:minBadValue}"
+
+	def worseInt = minBadInt + 42
+	redef defWorseValue equs "def worseValue = {d:worseInt}.0"
+	{defWorseValue}
+	println "Q.{2d:precision}: worse   = 1 << {2d:magnitude} + 42 = {11d:worseInt}.0 = {#09x:worseValue}"
+endr
--- a/test/asm/fixed-point-magnitude.err
+++ b/test/asm/fixed-point-magnitude.err
@@ -1,4 +1,183 @@
-warning: fixed-point-magnitude.asm(12): [-Wlarge-constant]
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~1(12): [-Wlarge-constant]
     Magnitude of fixed-point constant is too large
-warning: fixed-point-magnitude.asm(13): [-Wlarge-constant]
+while expanding symbol "def minBadValue = -2147483648.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~2(12): [-Wlarge-constant]
     Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 1073741824.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~2(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 1073741866.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~3(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 536870912.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~3(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 536870954.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~4(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 268435456.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~4(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 268435498.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~5(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 134217728.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~5(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 134217770.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~6(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 67108864.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~6(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 67108906.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~7(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 33554432.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~7(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 33554474.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~8(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 16777216.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~8(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 16777258.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~9(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 8388608.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~9(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 8388650.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~10(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 4194304.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~10(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 4194346.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~11(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 2097152.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~11(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 2097194.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~12(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 1048576.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~12(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 1048618.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~13(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 524288.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~13(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 524330.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~14(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 262144.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~14(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 262186.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~15(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 131072.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~15(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 131114.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~16(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 65536.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~16(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 65578.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~17(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 32768.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~17(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 32810.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~18(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 16384.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~18(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 16426.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~19(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 8192.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~19(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 8234.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~20(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 4096.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~20(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 4138.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~21(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 2048.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~21(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 2090.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~22(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 1024.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~22(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 1066.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~23(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 512.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~23(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 554.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~24(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 256.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~24(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 298.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~25(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 128.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~25(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 170.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~26(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 64.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~26(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 106.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~27(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 32.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~27(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 74.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~28(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 16.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~28(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 58.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~29(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 8.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~29(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 50.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~30(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 4.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~30(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 46.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~31(12): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def minBadValue = 2.0"
+warning: fixed-point-magnitude.asm(1) -> fixed-point-magnitude.asm::REPT~31(17): [-Wlarge-constant]
+    Magnitude of fixed-point constant is too large
+while expanding symbol "def worseValue = 44.0"
--- a/test/asm/fixed-point-magnitude.out
+++ b/test/asm/fixed-point-magnitude.out
@@ -1,12 +1,93 @@
-$10
-$FFFFFFF0
-$1
-$FFFFFFFF
-$74
-$FFFFFF8C
-$C4
-$FFFFFF3C
-$FF
-$FFFFFF01
-$140
-$FFFFFEC0
+Q. 1: max ok  = 1 << 31 - 1  =  2147483647.0 = $fffffffe
+Q. 1: min bad = 1 << 31      = -2147483648.0 = $00000000
+Q. 1: worse   = 1 << 31 + 42 = -2147483606.0 = $00000054
+Q. 2: max ok  = 1 << 30 - 1  =  1073741823.0 = $fffffffc
+Q. 2: min bad = 1 << 30      =  1073741824.0 = $00000000
+Q. 2: worse   = 1 << 30 + 42 =  1073741866.0 = $000000a8
+Q. 3: max ok  = 1 << 29 - 1  =   536870911.0 = $fffffff8
+Q. 3: min bad = 1 << 29      =   536870912.0 = $00000000
+Q. 3: worse   = 1 << 29 + 42 =   536870954.0 = $00000150
+Q. 4: max ok  = 1 << 28 - 1  =   268435455.0 = $fffffff0
+Q. 4: min bad = 1 << 28      =   268435456.0 = $00000000
+Q. 4: worse   = 1 << 28 + 42 =   268435498.0 = $000002a0
+Q. 5: max ok  = 1 << 27 - 1  =   134217727.0 = $ffffffe0
+Q. 5: min bad = 1 << 27      =   134217728.0 = $00000000
+Q. 5: worse   = 1 << 27 + 42 =   134217770.0 = $00000540
+Q. 6: max ok  = 1 << 26 - 1  =    67108863.0 = $ffffffc0
+Q. 6: min bad = 1 << 26      =    67108864.0 = $00000000
+Q. 6: worse   = 1 << 26 + 42 =    67108906.0 = $00000a80
+Q. 7: max ok  = 1 << 25 - 1  =    33554431.0 = $ffffff80
+Q. 7: min bad = 1 << 25      =    33554432.0 = $00000000
+Q. 7: worse   = 1 << 25 + 42 =    33554474.0 = $00001500
+Q. 8: max ok  = 1 << 24 - 1  =    16777215.0 = $ffffff00
+Q. 8: min bad = 1 << 24      =    16777216.0 = $00000000
+Q. 8: worse   = 1 << 24 + 42 =    16777258.0 = $00002a00
+Q. 9: max ok  = 1 << 23 - 1  =     8388607.0 = $fffffe00
+Q. 9: min bad = 1 << 23      =     8388608.0 = $00000000
+Q. 9: worse   = 1 << 23 + 42 =     8388650.0 = $00005400
+Q.10: max ok  = 1 << 22 - 1  =     4194303.0 = $fffffc00
+Q.10: min bad = 1 << 22      =     4194304.0 = $00000000
+Q.10: worse   = 1 << 22 + 42 =     4194346.0 = $0000a800
+Q.11: max ok  = 1 << 21 - 1  =     2097151.0 = $fffff800
+Q.11: min bad = 1 << 21      =     2097152.0 = $00000000
+Q.11: worse   = 1 << 21 + 42 =     2097194.0 = $00015000
+Q.12: max ok  = 1 << 20 - 1  =     1048575.0 = $fffff000
+Q.12: min bad = 1 << 20      =     1048576.0 = $00000000
+Q.12: worse   = 1 << 20 + 42 =     1048618.0 = $0002a000
+Q.13: max ok  = 1 << 19 - 1  =      524287.0 = $ffffe000
+Q.13: min bad = 1 << 19      =      524288.0 = $00000000
+Q.13: worse   = 1 << 19 + 42 =      524330.0 = $00054000
+Q.14: max ok  = 1 << 18 - 1  =      262143.0 = $ffffc000
+Q.14: min bad = 1 << 18      =      262144.0 = $00000000
+Q.14: worse   = 1 << 18 + 42 =      262186.0 = $000a8000
+Q.15: max ok  = 1 << 17 - 1  =      131071.0 = $ffff8000
+Q.15: min bad = 1 << 17      =      131072.0 = $00000000
+Q.15: worse   = 1 << 17 + 42 =      131114.0 = $00150000
+Q.16: max ok  = 1 << 16 - 1  =       65535.0 = $ffff0000
+Q.16: min bad = 1 << 16      =       65536.0 = $00000000
+Q.16: worse   = 1 << 16 + 42 =       65578.0 = $002a0000
+Q.17: max ok  = 1 << 15 - 1  =       32767.0 = $fffe0000
+Q.17: min bad = 1 << 15      =       32768.0 = $00000000
+Q.17: worse   = 1 << 15 + 42 =       32810.0 = $00540000
+Q.18: max ok  = 1 << 14 - 1  =       16383.0 = $fffc0000
+Q.18: min bad = 1 << 14      =       16384.0 = $00000000
+Q.18: worse   = 1 << 14 + 42 =       16426.0 = $00a80000
+Q.19: max ok  = 1 << 13 - 1  =        8191.0 = $fff80000
+Q.19: min bad = 1 << 13      =        8192.0 = $00000000
+Q.19: worse   = 1 << 13 + 42 =        8234.0 = $01500000
+Q.20: max ok  = 1 << 12 - 1  =        4095.0 = $fff00000
+Q.20: min bad = 1 << 12      =        4096.0 = $00000000
+Q.20: worse   = 1 << 12 + 42 =        4138.0 = $02a00000
+Q.21: max ok  = 1 << 11 - 1  =        2047.0 = $ffe00000
+Q.21: min bad = 1 << 11      =        2048.0 = $00000000
+Q.21: worse   = 1 << 11 + 42 =        2090.0 = $05400000
+Q.22: max ok  = 1 << 10 - 1  =        1023.0 = $ffc00000
+Q.22: min bad = 1 << 10      =        1024.0 = $00000000
+Q.22: worse   = 1 << 10 + 42 =        1066.0 = $0a800000
+Q.23: max ok  = 1 <<  9 - 1  =         511.0 = $ff800000
+Q.23: min bad = 1 <<  9      =         512.0 = $00000000
+Q.23: worse   = 1 <<  9 + 42 =         554.0 = $15000000
+Q.24: max ok  = 1 <<  8 - 1  =         255.0 = $ff000000
+Q.24: min bad = 1 <<  8      =         256.0 = $00000000
+Q.24: worse   = 1 <<  8 + 42 =         298.0 = $2a000000
+Q.25: max ok  = 1 <<  7 - 1  =         127.0 = $fe000000
+Q.25: min bad = 1 <<  7      =         128.0 = $00000000
+Q.25: worse   = 1 <<  7 + 42 =         170.0 = $54000000
+Q.26: max ok  = 1 <<  6 - 1  =          63.0 = $fc000000
+Q.26: min bad = 1 <<  6      =          64.0 = $00000000
+Q.26: worse   = 1 <<  6 + 42 =         106.0 = $a8000000
+Q.27: max ok  = 1 <<  5 - 1  =          31.0 = $f8000000
+Q.27: min bad = 1 <<  5      =          32.0 = $00000000
+Q.27: worse   = 1 <<  5 + 42 =          74.0 = $50000000
+Q.28: max ok  = 1 <<  4 - 1  =          15.0 = $f0000000
+Q.28: min bad = 1 <<  4      =          16.0 = $00000000
+Q.28: worse   = 1 <<  4 + 42 =          58.0 = $a0000000
+Q.29: max ok  = 1 <<  3 - 1  =           7.0 = $e0000000
+Q.29: min bad = 1 <<  3      =           8.0 = $00000000
+Q.29: worse   = 1 <<  3 + 42 =          50.0 = $40000000
+Q.30: max ok  = 1 <<  2 - 1  =           3.0 = $c0000000
+Q.30: min bad = 1 <<  2      =           4.0 = $00000000
+Q.30: worse   = 1 <<  2 + 42 =          46.0 = $80000000
+Q.31: max ok  = 1 <<  1 - 1  =           1.0 = $80000000
+Q.31: min bad = 1 <<  1      =           2.0 = $00000000
+Q.31: worse   = 1 <<  1 + 42 =          44.0 = $00000000