( Title: Regression tests for ieeefp-ext.c File: ieeefp-ext-test.fs Version: 0.5.5 Revised: July 1, 2010 Author: David N. Williams License: Public Domain These tests are expected to work only on 32-bit systems. The date above may reflect cosmetic changes not logged here. Version 0.5.5 02Oct09 * Tests for setting rounding mode state. * Tests for exception flag state 03Oct09 * Tests for rounding calculation. * Tests for exceptions on calculation. * Tests for FNEXTUP and FNEXTDOWN. * Tests for alternate exception state. 28Jun10 * Added Krishna Myneni's terminal colors. * Tests for alternate exception stopping. 29Jun10 * Revised .EXCEPTS and renamed as .FAE. * Added trailing F. to alternate exception stopping tests because of alternate exception imprecision with linux. * Tests for GET-FHANDLER, SET-FHANDLER, INSTALL-FHANDLING. 01Jul10 * Revised alternate stopping commentary and tests to distinguish between pre- and post-computation exceptions for intel x87. ) \ DEBUGGING [UNDEFINED] \\ [IF] : \\ ( -- ) -1 parse 2drop BEGIN refill 0= UNTIL ; [THEN] [UNDEFINED] HEX. [IF] : HEX. ( u -- ) base @ >r hex . r> base ! ; [THEN] loadm ieeefp 0e fabs fconstant +0 +0 fnegate fconstant -0 s" ttester.fs" included \ raises inexact flag TRUE VERBOSE ! set-exact decimal \ Turn this off if it causes a problem with your terminal. TRUE VALUE ANSI-TERMINAL-COLORS : ?.cr ( -- ) VERBOSE @ IF cr THEN ; ?.cr variable #errors 0 #errors ! ANSI-TERMINAL-COLORS [IF] \ Krishna Myneni : normal-text ( -- ) 27 emit [char] [ emit [char] 0 emit [char] m emit ; : red-text ( -- ) 27 emit [char] [ emit ." 31m" ; : green-text ( -- ) 27 emit [char] [ emit ." 32m" ; : blue-text ( -- ) 27 emit [char] [ emit ." 34m" ; [ELSE] : normal-text ( -- ) ; : red-text ( -- ) ; : green-text ( -- ) ; : blue-text ( -- ) ; [THEN] :noname ( c-addr u -- ) ( Display an error message followed by the line that had the error. ) red-text 1 #errors +! error1 normal-text ; ERROR-XT ! : ?.errors ( -- ) VERBOSE @ IF blue-text ." #ERRORS: " normal-text #errors @ . THEN ; : COMMENT ( -- ) \ Krishna Myneni blue-text source >in @ /string VERBOSE @ IF type cr ELSE 2drop THEN source >in ! drop normal-text ; \ Fails if bits/cell <> 32, or not two's complement: s" mixfloat.fs" included \ for mixed hex/decimal input, MIX>F decimal s" 1.F FFFF FFFF FFFF p+1023" mix>f fconstant max-+n s" 1.0 0000 0000 0000 p-1022" mix>f fconstant min-+n s" 0.F FFFF FFFF FFFF p-1022" mix>f fconstant max-+subn s" 0.0 0000 0000 0001 p-1022" mix>f fconstant min-+subn s" -0.0 0000 0000 0001 p-1022" mix>f fconstant -min-+subn s" -0.F FFFF FFFF FFFF p-1022" mix>f fconstant -max-+subn s" -1.0 0000 0000 0000 p-1022" mix>f fconstant -min-+n s" -1.F FFFF FFFF FFFF p+1023" mix>f fconstant -max-+n s" 1.0 0000 0000 0001 p-1022" mix>f fconstant min-+n-up s" -1.0 0000 0000 0001 p-1022" mix>f fconstant [-min-+n]-down s" 1.0 0000 0000 0001 p0" mix>f fconstant 1-up s" 1.F FFFF FFFF FFFF p-1" mix>f fconstant 1-down s" -1.F FFFF FFFF FFFF p-1" mix>f fconstant [-1]-up s" -1.0 0000 0000 0001 p0" mix>f fconstant [-1]-down s" 1.0 0000 0000 0001 p1" mix>f fconstant 2-up s" 1.F FFFF FFFF FFFF p0" mix>f fconstant 2-down s" -1.F FFFF FFFF FFFF p0" mix>f fconstant [-2]-up s" -1.0 0000 0000 0001 p1" mix>f fconstant [-2]-down s" 1.F FFFF FFFF FFFE p+1023" mix>f fconstant max-+n-down s" -1.F FFFF FFFF FFFE p+1023" mix>f fconstant [-max-+n]-up testing FNEXTUP \ nan propagation t{ +nan FNEXTUP -> +nan }t t{ -nan FNEXTUP -> -nan }t \ max-+n boundary t{ +inf FNEXTUP -> +inf }t t{ max-+n FNEXTUP -> +inf }t t{ max-+n-down FNEXTUP -> max-+n }t \ +normal integer boundaries t{ 2e FNEXTUP -> 2-up }t t{ 2-down FNEXTUP -> 2e }t t{ 1e FNEXTUP -> 1-up }t t{ 1-down FNEXTUP -> 1e }t \ +subnormal boundaries t{ min-+subn FNEXTUP -> min-+subn f2* }t t{ max-+subn FNEXTUP -> min-+n }t t{ min-+n FNEXTUP -> min-+n-up }t \ +/-0 boundaries t{ +0 FNEXTUP -> min-+subn }t t{ -0 FNEXTUP -> min-+subn }t t{ -min-+subn FNEXTUP -> -0 }t \ -subnormal boundaries t{ -min-+subn f2* FNEXTUP -> -min-+subn }t t{ [-min-+n]-down FNEXTUP -> -min-+n }t t{ -min-+n FNEXTUP -> -max-+subn }t \ -normal integer boundaries t{ -1e FNEXTUP -> [-1]-up }t t{ [-1]-down FNEXTUP -> -1e }t t{ -2e FNEXTUP -> [-2]-up }t t{ [-2]-down FNEXTUP -> -2e }t \ -max-+n boundary t{ -max-+n FNEXTUP -> [-max-+n]-up }t t{ -inf FNEXTUP -> -max-+n }t testing FNEXTDOWN \ nan propagation t{ +nan FNEXTDOWN -> +nan }t t{ -nan FNEXTDOWN -> -nan }t \ max-+n boundary t{ +inf FNEXTDOWN -> max-+n }t t{ max-+n FNEXTDOWN -> max-+n-down }t \ +normal integer boundaries t{ 2-up FNEXTDOWN -> 2e }t t{ 2e FNEXTDOWN -> 2-down }t t{ 1-up FNEXTDOWN -> 1e }t t{ 1e FNEXTDOWN -> 1-down }t \ +subnormal boundaries t{ min-+n-up FNEXTDOWN -> min-+n }t t{ min-+n FNEXTDOWN -> max-+subn }t t{ min-+subn f2* FNEXTDOWN -> min-+subn }t \ +/-0 boundaries t{ min-+subn FNEXTDOWN -> +0 }t t{ +0 FNEXTDOWN -> -min-+subn }t t{ -0 FNEXTDOWN -> -min-+subn }t \ -subnormal boundaries t{ -min-+subn FNEXTDOWN -> -min-+subn f2* }t t{ -max-+subn FNEXTDOWN -> -min-+n }t t{ -min-+n FNEXTDOWN -> [-min-+n]-down }t \ -normal integer boundaries t{ [-1]-up FNEXTDOWN -> -1e }t t{ -1e FNEXTDOWN -> [-1]-down }t t{ [-2]-up FNEXTDOWN -> -2e }t t{ -2e FNEXTDOWN -> [-2]-down }t \ -max-+n boundary t{ [-max-+n]-up FNEXTDOWN -> -max-+n }t t{ -max-+n FNEXTDOWN -> -inf }t t{ -inf FNEXTDOWN -> -inf }t testing rounding t{ fegetround -> FE-TONEAREST }t \ default t{ FE-DOWNWARD fesetround fegetround -> FE-DOWNWARD }t t{ FE-UPWARD fesetround fegetround -> FE-UPWARD }t t{ FE-TOWARDZERO fesetround fegetround -> FE-TOWARDZERO }t t{ FE-TONEAREST fesetround fegetround -> FE-TONEAREST }t ( The hex-digit double calculations below are enough to distinguish all the rounding cases. "Rounds" means the exact result has more than 53 bits of significance. "Exact" means the exact result has exactly 53 significant bits. A criterion for the tests is that at least one result shall be different for each rounding mode, and of course that all results shall be correct. The roundTiesToEven mode has the richest set of possibilities, and determines how many tests are needed. 1.0 0000 0000 0000 #1 + 0.0 0000 0000 0000 8 = 2^-53 ---------------------- 1.0 0000 0000 0000 8 rounds 1.0 0000 0000 0001 #2 + 0.0 0000 0000 0000 8 ---------------------- 1.0 0000 0000 0001 8 rounds 0.F FFFF FFFF FFFF 8 #3 + 0.0 0000 0000 0000 4 = 2^-54 ---------------------- 0.F FFFF FFFF FFFF C rounds 1.0 0000 0000 0000 #4 - 0.0 0000 0000 0000 8 ---------------------- 0.F FFFF FFFF FFFF 8 exact = 1-down 1.0 0000 0000 0001 #5 - 0.0 0000 0000 0000 8 ---------------------- 1.0 0000 0000 0000 8 rounds 0.F FFFF FFFF FFFF 8 #6 - 0.0 0000 0000 0000 4 = 2^-54 ---------------------- 0.F FFFF FFFF FFFF 4 rounds -1.0 0000 0000 0000 #7 + 0.0 0000 0000 0000 8 = 2^-53 ---------------------- -0.F FFFF FFFF FFFF 8 exact = [-1]-up -1.0 0000 0000 0001 #8 + 0.0 0000 0000 0000 8 ---------------------- -1.0 0000 0000 0000 8 rounds -0.F FFFF FFFF FFFF 8 #9 + 0.0 0000 0000 0000 4 = 2^-54 ---------------------- -0.F FFFF FFFF FFFF 4 rounds -1.0 0000 0000 0000 #10 - 0.0 0000 0000 0000 8 ---------------------- -1.0 0000 0000 0000 8 rounds -1.0 0000 0000 0001 #11 - 0.0 0000 0000 0000 8 ---------------------- -1.0 0000 0000 0001 8 rounds -0.F FFFF FFFF FFFF 8 #12 - 0.0 0000 0000 0000 4 = 2^-54 ---------------------- -0.F FFFF FFFF FFFF C rounds ) 1e fnextup 1e f- f2/ fconstant 2^-53 2^-53 f2/ fconstant 2^-54 FE-TONEAREST fesetround t{ 1e 2^-53 f+ -> 1e }t \ #1 t{ 1-up 2^-53 f+ -> 1-up fnextup }t \ #2 t{ 1-down 2^-54 f+ -> 1e }t \ #3 t{ 1e 2^-53 f- -> 1-down }t \ #4 t{ 1-up 2^-53 f- -> 1e }t \ #5 t{ 1-down 2^-54 f- -> 1-down fnextdown }t \ #6 t{ -1e 2^-53 f+ -> [-1]-up }t \ #7 t{ [-1]-down 2^-53 f+ -> -1e }t \ #8 t{ [-1]-up 2^-54 f+ -> [-1]-up fnextup }t \ #9 t{ -1e 2^-53 f- -> -1e }t \ #10 t{ [-1]-down 2^-53 f- -> [-1]-down fnextdown }t \ #11 t{ [-1]-up 2^-54 f- -> -1e }t \ #12 FE-TOWARDZERO fesetround t{ 1e 2^-53 f+ -> 1e }t \ #1 t{ 1-up 2^-53 f+ -> 1-up }t \ #2 t{ 1-down 2^-54 f+ -> 1-down }t \ #3 t{ 1e 2^-53 f- -> 1-down }t \ #4 t{ 1-up 2^-53 f- -> 1e }t \ #5 t{ 1-down 2^-54 f- -> 1-down fnextdown }t \ #6 t{ -1e 2^-53 f+ -> [-1]-up }t \ #7 t{ [-1]-down 2^-53 f+ -> -1e }t \ #8 t{ [-1]-up 2^-54 f+ -> [-1]-up fnextup }t \ #9 t{ -1e 2^-53 f- -> -1e }t \ #10 t{ [-1]-down 2^-53 f- -> [-1]-down }t \ #11 t{ [-1]-up 2^-54 f- -> [-1]-up }t \ #12 FE-UPWARD fesetround t{ 1e 2^-53 f+ -> 1-up }t \ #1 t{ 1-up 2^-53 f+ -> 1-up fnextup }t \ #2 t{ 1-down 2^-54 f+ -> 1e }t \ #3 t{ 1e 2^-53 f- -> 1-down }t \ #4 t{ 1-up 2^-53 f- -> 1-up }t \ #5 t{ 1-down 2^-54 f- -> 1-down }t \ #6 t{ -1e 2^-53 f+ -> [-1]-up }t \ #7 t{ [-1]-down 2^-53 f+ -> -1e }t \ #8 t{ [-1]-up 2^-54 f+ -> [-1]-up fnextup }t \ #9 t{ -1e 2^-53 f- -> -1e }t \ #10 t{ [-1]-down 2^-53 f- -> [-1]-down }t \ #11 t{ [-1]-up 2^-54 f- -> [-1]-up }t \ #12 FE-DOWNWARD fesetround t{ 1e 2^-53 f+ -> 1e }t \ #1 t{ 1-up 2^-53 f+ -> 1-up }t \ #2 t{ 1-down 2^-54 f+ -> 1-down }t \ #3 t{ 1e 2^-53 f- -> 1-down }t \ #4 t{ 1-up 2^-53 f- -> 1e }t \ #5 t{ 1-down 2^-54 f- -> 1-down fnextdown }t \ #6 t{ -1e 2^-53 f+ -> [-1]-up }t \ #7 t{ [-1]-down 2^-53 f+ -> [-1]-down }t \ #8 t{ [-1]-up 2^-54 f+ -> [-1]-up }t \ #9 t{ -1e 2^-53 f- -> [-1]-down }t \ #10 t{ [-1]-down 2^-53 f- -> [-1]-down fnextdown }t \ #11 t{ [-1]-up 2^-54 f- -> -1e }t \ #12 FE-TONEAREST fesetround \ restore default testing exception flags : allfl@ ( -- excepts ) ALL-FEXCEPTS get-fflags ; : 0allfl ( -- ) ALL-FEXCEPTS clear-fflags ; t{ allfl@ -> FINEXACT }t \ raised by ttester t{ FINEXACT clear-fflags allfl@ -> 0 }t t{ FDIVBYZERO set-fflags allfl@ -> FDIVBYZERO }t t{ FOVERFLOW set-fflags allfl@ -> FDIVBYZERO FOVERFLOW or }t \ no inexact on overflow t{ FINEXACT set-fflags allfl@ -> FDIVBYZERO FOVERFLOW FINEXACT or or }t t{ FUNDERFLOW set-fflags allfl@ -> FDIVBYZERO FOVERFLOW FINEXACT FUNDERFLOW or or or }t t{ FINVALID set-fflags allfl@ -> ALL-FEXCEPTS }t t{ FDIVBYZERO clear-fflags allfl@ -> ALL-FEXCEPTS FDIVBYZERO xor }t t{ FOVERFLOW clear-fflags allfl@ -> ALL-FEXCEPTS FDIVBYZERO xor FOVERFLOW xor }t t{ FUNDERFLOW FINEXACT FINVALID or or clear-fflags allfl@ -> 0 }t t{ 0allfl 3e 0e f/ fdrop allfl@ -> FDIVBYZERO }t t{ 0allfl 0e 0e f/ fdrop allfl@ -> FINVALID }t t{ 0allfl 1.5E+308 1E-3 f/ fdrop allfl@ -> FOVERFLOW FINEXACT or }t t{ 0allfl 1E-3 1.5E+308 f/ fdrop allfl@ -> FUNDERFLOW FINEXACT or }t t{ 0allfl 1e 2^-54 f+ fdrop allfl@ -> FINEXACT }t t{ 0allfl 1e 2^-53 f+ allfl@ -> 1e FINEXACT }t \ exact rounding 0allfl testing alternate exception state : 0allfae ( -- ) ALL-FEXCEPTS fdisable ; \ DEBUGGING : .fae ( -- excepts ) fenabled dup cr ." EXCEPTS: 0x" hex. dup FDIVBYZERO and IF ." FDIVBYZERO " THEN dup FINVALID and IF ." FINVALID " THEN dup FOVERFLOW and IF ." FOVERFLOW " THEN dup FUNDERFLOW and IF ." FUNDERFLOW " THEN FINEXACT and IF ." FINEXACT " THEN cr ; : my-fhandler ( throw -- ) cr ." MY-FHANDLER: throw = " dup . throw ; t{ get-fhandler -> ' throw }t t{ ' my-fhandler set-fhandler -> }t t{ get-fhandler -> ' my-fhandler }t t{ install-fhandling -> }t t{ get-fhandler -> ' throw }t t{ fenabled -> 0 }t \ system default t{ 0allfae -> }t t{ fenabled -> 0 }t t{ FDIVBYZERO fenable fenabled -> FDIVBYZERO }t t{ FINVALID fenable fenabled -> FDIVBYZERO FINVALID or }t t{ FOVERFLOW FUNDERFLOW FINEXACT or or fenable fenabled -> ALL-FEXCEPTS }t t{ FUNDERFLOW fdisable fenabled -> ALL-FEXCEPTS FUNDERFLOW invert and }t t{ 0allfae fenabled -> 0 }t ' my-fhandler set-fhandler ( Uncomment one of the following to test an alternate, stopping exception. The trailing F. on the last three below caters to the intel Linux we use, whose gcc defaults to the x87 instead of the SIMD fpu. With intel, the last three are post-computation exceptions, which do not trigger until the next fp operation, F. in this case. The first two are precomputation exceptions, which trigger at the operation. Furthermore, alternate exceptions are imprecise for x87. For example, substituting an fp number for F. produces a segmentation fault in our Linux tests, without calling the fhandler. The exceptions are precise with the ppc and intel SIMD fpu's. SIMD is the default for Snow Leopard. The trailing F. is superfluous for testing with Leopard ppc and Snow Leopard intel. ) \ FDIVBYZERO fenable 1e 0e f/ \ FINVALID fenable 0e 0e f/ \ FOVERFLOW fenable 1.5E+308 1E-3 f/ f. \ FUNDERFLOW fenable 1E-3 1.5E+308 f/ f. \ FINEXACT fenable 1e 2^-54 f+ f. ?.errors ?.cr