testing trig and log

This commit is contained in:
~d6 2022-11-07 14:52:29 -05:00
parent b4104e2c7d
commit 4e93396b4d
2 changed files with 43 additions and 8 deletions

View File

@ -117,7 +117,7 @@
&<100 DUP #0a LTH ,&<10 JCN
&>=10 #0a DIVk DUP x16-emit-dec-digit MUL SUB
&<10 x16-emit-dec-digit
LIT '. #18 DEO
LIT ". #18 DEO
( emit fractional part )
#00 SWP ( lo* )
#000a MUL2 #0100 DIV2k DUP2 NIP x16-emit-dec-digit MUL2 SUB2

View File

@ -1,33 +1,53 @@
#!/usr/bin/python
from math import floor, log
from math import floor, log, sin, cos, tan, copysign
from os import environ
from random import randint
from subprocess import Popen, PIPE, run
def tosigned(x):
return x if x < 32768 else x - 65536
u8 = {'sz': 1 << 8, 'fmt': b'%02x'}
u16 = {'sz': 1 << 16, 'fmt': b'%04x'}
z16 = {'sz': 1 << 16, 'fmt': b'%04x'}
p16 = {'sz': 1 << 16, 'fmt': b'%04x'}
t16 = {'sz': 1 << 16, 'fmt': b'%04x'}
def eq(got, expected):
return got == expected
def booleq(got, expected):
return bool(got) == bool(expected)
def releq(got, expected):
def releq(got0, expected0):
got, expected = tosigned(got0), tosigned(expected0)
if (expected - 1) <= got and got <= (expected + 1):
return True
else:
error = abs(got - expected) / (abs(expected) + 0.001)
return error < 0.01
def abseq(got0, expected0):
got, expected = tosigned(got0), tosigned(expected0)
if (expected - 10) <= got and got <= (expected + 10):
return True
else:
return False
def taneq(got0, expected0):
got, expected = tosigned(got0), tosigned(expected0)
if (expected - 1) <= got and got <= (expected + 1):
return True
else:
error = abs(got - expected) / (abs(expected) + 0.001)
return error < 0.1
def testcase(p, sym, args, out, f, eq):
vals = []
for name, g in args:
val = randint(0, g['sz'] - 1)
while val == 0 and g is z16:
while ((val == 0 and (g is z16 or g is p16)) or
(val >= 0x8000 and g is p16) or
(g is t16 and ((val >= 804) or ((val % 804) == 402)))):
val = randint(0, g['sz'] - 1)
vals.append((name, g, val))
#vals = [(name, g, randint(0, g['sz'] - 1)) for (name, g) in args]
p.stdin.write(sym)
for _, g, x in vals:
p.stdin.write(g['fmt'] % x)
@ -85,8 +105,6 @@ def x16_eq(x, y):
return x == y
def x16_ne(x, y):
return x != y
def tosigned(x):
return x if x < 32768 else x - 65536
def x16_lt(x, y):
return int(tosigned(x) < tosigned(y))
def x16_gt(x, y):
@ -95,9 +113,22 @@ def x16_lteq(x, y):
return int(tosigned(x) <= tosigned(y))
def x16_gteq(x, y):
return int(tosigned(x) >= tosigned(y))
def x16_sin(x):
z = round(sin(x / 256) * 256)
return z if z >= 0 else 65536 + z
def x16_cos(x):
z = round(cos(x / 256) * 256)
return z if z >= 0 else 65536 + z
def x16_tan(x):
z0 = round(tan(x / 256) * 256)
z = min(max(z0, -0x7fff), 0x7fff)
return z if z >= 0 else 65536 + z
def x16_log(x):
z = round(log(x / 256) * 256)
return z if z >= 0 else 65536 + z
def main():
trials = 100000
trials = 10000
run(['uxnasm', 'test-fix16.tal', 'run.rom'])
p = pipe()
test(p, trials, b'+', [('x', u16), ('y', u16)], u16, x16_add)
@ -114,6 +145,10 @@ def main():
test(p, trials, b'>', [('x', u16), ('y', u16)], u8, x16_gt)
test(p, trials, b'{', [('x', u16), ('y', u16)], u8, x16_lteq)
test(p, trials, b'}', [('x', u16), ('y', u16)], u8, x16_gteq)
test(p, trials, b's', [('x', p16)], u16, x16_sin, eq=abseq)
test(p, trials, b'c', [('x', p16)], u16, x16_cos, eq=abseq)
test(p, trials, b't', [('x', t16)], u16, x16_tan, eq=taneq)
test(p, trials, b'l', [('x', p16)], u16, x16_log, eq=releq)
p.stdin.write(b'\n\n')
p.stdin.flush()
p.stdin.close()