mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2025-07-01 23:58:20 +00:00
Improve NaN tests to properly check for indeterminates.
One big disappointment is that Python doesn't allow redefining float.__repr__, leading to a much increased difficulty in checking and reporting differences in NaN vs. Indet. We do what we can, though. We re-enable the recursive comparison as opposed to the repr comparison. As a result, many of the tests reported wrong results. Fixed them. Fix also a problem with comparing infinities (they can't be compared to a tolerance). This commit also changes the struct.pack check to math.copysing as in the previous commit.
This commit is contained in:
parent
60f257279b
commit
c2560303dc
1 changed files with 30 additions and 14 deletions
44
testfuncs.py
44
testfuncs.py
|
@ -39,6 +39,14 @@ class ETestFailed(Exception):
|
|||
super(self.__class__, self).__init__("Test failed")
|
||||
pass
|
||||
|
||||
# Not failproof because we can't redefine float.__repr__
|
||||
# so floats in vectors/rotations/lists aren't handled.
|
||||
class newfloat(float):
|
||||
def __repr__(n):
|
||||
if not math.isnan(n):
|
||||
return float.__repr__(n)
|
||||
return '-nan' if math.copysign(1, n) < 0 else 'nan'
|
||||
|
||||
def reallyequal(actual, expected, tol):
|
||||
if tol is None:
|
||||
return repr(actual) == repr(expected)
|
||||
|
@ -50,10 +58,11 @@ def reallyequal(actual, expected, tol):
|
|||
if isinstance(actual, float):
|
||||
if actual == 0.0:
|
||||
return repr(actual) == repr(expected)
|
||||
elif math.isnan(actual):
|
||||
if math.isnan(actual):
|
||||
# This compares the sign of NaN as well
|
||||
from struct import pack
|
||||
return pack('>f', actual) == pack('>f', expected)
|
||||
return math.isnan(expected) and math.copysign(1, actual) == math.copysign(1, expected)
|
||||
if math.isinf(actual) and math.isinf(expected):
|
||||
return actual == expected
|
||||
return abs(actual - expected) <= tol
|
||||
|
||||
# Deal with tuples and lists (item-by-item, recursively)
|
||||
|
@ -67,7 +76,7 @@ def test(fn, expected):
|
|||
global tests
|
||||
global errors
|
||||
global untested
|
||||
tol = None # get rid of tolerance test
|
||||
tol = 0.0 # compare to zero tolerance
|
||||
tests += 1
|
||||
if StopAtFirstError:
|
||||
if errors:
|
||||
|
@ -75,6 +84,10 @@ def test(fn, expected):
|
|||
return
|
||||
|
||||
actual = eval(fn)
|
||||
if isinstance(actual, float):
|
||||
actual = newfloat(actual)
|
||||
if isinstance(expected, float):
|
||||
expected = newfloat(expected)
|
||||
werr = sys.stderr.write
|
||||
if not reallyequal(actual, expected, tol):
|
||||
werr("Test failed: " + fn + '\n')
|
||||
|
@ -492,6 +505,8 @@ def test_jira_fixes():
|
|||
# End JSON tests from wiki
|
||||
|
||||
def do_tests():
|
||||
# Test our own test function for NaNs
|
||||
test('reallyequal(NaN, Indet, 0.0)', False)
|
||||
|
||||
shouldexcept('div(1.0, 0.0)', ELSLMathError)
|
||||
shouldexcept('div(1, 0)', ELSLMathError)
|
||||
|
@ -787,10 +802,10 @@ def do_tests():
|
|||
exp = [
|
||||
NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,
|
||||
NaN,0.,0.,0.,0.,0.,1.,1.,Infinity,-Infinity,Infinity,Infinity,Infinity,
|
||||
NaN,0.,NaN,F('0x1.D0662Ep-3'),F('-0x1.E79E7Cp-2'),NaN,1.,1.,NaN,F('-0x1.0CCCCCp+1'),F('0x1.1A3D6Ep+2'),NaN,Infinity,
|
||||
NaN,0.,NaN,.25,-0.5,NaN,1.,1.,NaN,-2.,4.,NaN,Infinity,
|
||||
NaN,NaN,NaN,1.,-1.,NaN,1.,1.,NaN,-1.,1.,NaN,NaN,
|
||||
NaN,Infinity,NaN,100.,-10.,NaN,1.,1.,NaN,F('-0x1.99999Ap-4'),F('0x1.47AE16p-7'),NaN,0.,
|
||||
NaN,0.,Indet,F('0x1.D0662Ep-3'),F('-0x1.E79E7Cp-2'),Indet,1.,1.,Indet,F('-0x1.0CCCCCp+1'),F('0x1.1A3D6Ep+2'),Indet,Infinity,
|
||||
NaN,0.,Indet,.25,-0.5,Indet,1.,1.,Indet,-2.,4.,Indet,Infinity,
|
||||
NaN,NaN,Indet,1.,-1.,Indet,1.,1.,Indet,-1.,1.,Indet,NaN,
|
||||
NaN,Infinity,Indet,100.,-10.,Indet,1.,1.,Indet,F('-0x1.99999Ap-4'),F('0x1.47AE16p-7'),Indet,0.,
|
||||
NaN,Infinity,Infinity,Infinity,-Infinity,Infinity,1.,1.,0.,0.,0.,0.,0.,
|
||||
NaN,Infinity,Infinity,Infinity,Infinity,Infinity,1.,1.,0.,0.,0.,0.,0.,
|
||||
NaN,Infinity,F('0x1.F791EEp+6'),100.,10.,F('0x1.4248F0p0'),1.,1.,F('0x1.96B230p-1'),F('0x1.99999Ap-4'),F('0x1.47AE16p-7'),F('0x1.04491Ap-7'),0.,
|
||||
|
@ -807,8 +822,8 @@ def do_tests():
|
|||
idx += 1
|
||||
|
||||
test('llCos(NaN)', NaN)
|
||||
test('llCos(Infinity)', NaN)
|
||||
test('llCos(-Infinity)', NaN)
|
||||
test('llCos(Infinity)', Indet)
|
||||
test('llCos(-Infinity)', Indet)
|
||||
test('llCos(math.pi)', -1.)
|
||||
test('llCos(1000.)', F('0x1.1FF026p-1'))
|
||||
test('llCos(1000000.)', F('0x1.DF9DFAp-1'))
|
||||
|
@ -817,8 +832,8 @@ def do_tests():
|
|||
#test('llCos(F("0x.FFFFFFp+63"))', F('-0x1.F4E122p-1')) # alas, doesn't match
|
||||
test('abs(llCos(F("0x.FFFFFFp+63")) - F("-0x1.F4E122p-1")) < 0.003', True) # workaround
|
||||
test('llSin(NaN)', NaN)
|
||||
test('llSin(Infinity)', NaN)
|
||||
test('llSin(-Infinity)', NaN)
|
||||
test('llSin(Infinity)', Indet)
|
||||
test('llSin(-Infinity)', Indet)
|
||||
test('llSin(F32(math.pi))', F('-0x1.777A5Cp-24'))
|
||||
test('llSin(1000.)', F('0x1.A75CC2p-1'))
|
||||
test('llSin(1000000.)', F('-0x1.6664B2p-2'))
|
||||
|
@ -828,7 +843,7 @@ def do_tests():
|
|||
#test('llSin(F("0x.FFFFFFp+63"))', F('0x1.A8862Cp-3')) # alas, doesn't match
|
||||
test('abs(llSin(F("0x.FFFFFFp+63")) - F("0x1.A8862Cp-3")) < 0.012', True) # workaround
|
||||
test('llTan(F32(1e38))', F32(1e38))
|
||||
test('llTan(F32(4e38))', NaN)
|
||||
test('llTan(F32(4e38))', Indet)
|
||||
test('llTan(F32(math.pi))', F('0x1.777A5Cp-24'))
|
||||
test('llTan(F32(math.pi*.5))', -22877330.)
|
||||
test('llTan(F("0x1.921FB4p0"))', 13245400.)
|
||||
|
@ -1028,7 +1043,8 @@ def do_tests():
|
|||
test('llModPow(41, 1, 17)', 7)
|
||||
|
||||
test('llListFindList([], [])', 0)
|
||||
test('llListFindList([NaN, -NaN], [-NaN, NaN])', 0) # I swear
|
||||
test('llListFindList([NaN], [NaN])', 0) # I swear.
|
||||
test('llListFindList([NaN, Indet], [Indet, NaN])', 0) # Indeed.
|
||||
test('llListFindList([-0.], [0.])', 0) # Really.
|
||||
test('llListFindList([0.], [-0.])', 0) # Yes.
|
||||
test('llListFindList([1, NaN, 1., NaN], [1., NaN])', 2)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue