rounding and conversions are tested and working

This commit is contained in:
~d6 2022-11-09 11:48:55 -05:00
parent 4e93396b4d
commit 020c0617bc
3 changed files with 102 additions and 21 deletions

View File

@ -67,6 +67,26 @@
( - log() is supported )
( - log(0) throws an error )
( - log values farther from zero may be a bit inaccurate )
( )
( rounding, truncation, conversion: )
( )
( - x16-to-s16: converts the whole to signed 16-bit, )
( discarding the fractional part. the )
( magnitude of numbers is never increased. )
( )
( - x16-to-s8: same as x16-to-s16 but returns one byte. )
( )
( - x16-ceil: returns a x16 value with any fractional )
( part rounded up. )
( )
( - x16-floor: returns a x16 value with any fractional )
( part rounded down. )
( )
( - x16-round: returns a x16 value with any fractional )
( part rounded up or down depending on the )
( fractional part. in the case of numbers )
( with a fractional part of 0.5, they will )
( round towards the nearest even value. )
( useful macros )
%x16-is-non-neg { x16-minimum LTH2 }
@ -199,6 +219,35 @@
@x16-remainder ( x* y* -> x%y* )
DIV2k MUL2 SUB2 JMP2r
( 1.5 -> 1, 0.5 -> 0, -1.5 -> -1 )
@x16-to-s16 ( x* -> whole* )
DUP2 #7fff GTH2 ,&neg JCN ( x0 x1 )
DUP EOR ( x0 00 )
SWP JMP2r ( 0 x0 )
&neg #00ff STHk ( x0 x1 00 ff [ff] )
ADD2 POP ( x0' [ff] )
DUP #07 SFT STHr ( x0' s' ff )
MUL SWP JMP2r ( 00-or-ff x0' )
( 1.5 -> 1, 0.5 -> 0, -1.5 -> -1 )
@x16-to-s8 ( x* -> whole^ )
DUP2 #0f SFT2 #00ff MUL2 ADD2 POP JMP2r
( e.g. #0812 -> #0800 )
@x16-floor ( x* -> floor(x)* )
DUP EOR JMP2r
( e.g. #0812 -> #0900 )
@x16-ceil ( x* -> floor(x)* )
#00ff ADD2 DUP EOR JMP2r
( round half-even, #0080 -> #0000, #0180 -> #0200 )
@x16-round ( x* -> round(x)* )
OVR #01 AND ,&odd JCN
( even ) #007f ,&rest JMP
&odd #0080
&rest ADD2 DUP EOR JMP2r
@x16-cos ( x* -> cos(x)* )
x16-pi/2 ADD2 ,x16-sin JMP

View File

@ -1,6 +1,6 @@
#!/usr/bin/python
from math import floor, log, sin, cos, tan, copysign
from math import ceil, copysign, cos, floor, log, sin, tan
from os import environ
from random import randint
from subprocess import Popen, PIPE, run
@ -126,9 +126,26 @@ def x16_tan(x):
def x16_log(x):
z = round(log(x / 256) * 256)
return z if z >= 0 else 65536 + z
def x16_floor(x):
return floor(x / 256) * 256
def x16_ceil(x):
return (ceil(x / 256) * 256) % 65536
def x16_round(x):
return (round(x / 256) * 256) % 65536
def x16_trunc16(x):
r = tosigned(x) / 256
if r < 0:
return (65536 + ceil(r)) % 65536
else:
return floor(x / 256)
def x16_trunc8(x):
if tosigned(x) < 0:
return ceil(x / 256) % 256
else:
return floor(x / 256)
def main():
trials = 10000
trials = 1000
run(['uxnasm', 'test-fix16.tal', 'run.rom'])
p = pipe()
test(p, trials, b'+', [('x', u16), ('y', u16)], u16, x16_add)
@ -149,6 +166,11 @@ def main():
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)
test(p, trials, b'F', [('x', u16)], u16, x16_floor)
test(p, trials, b'C', [('x', u16)], u16, x16_ceil)
test(p, trials, b'R', [('x', u16)], u16, x16_round)
test(p, trials, b'8', [('x', u16)], u16, x16_trunc8)
test(p, trials, b'T', [('x', u16)], u16, x16_trunc16)
p.stdin.write(b'\n\n')
p.stdin.flush()
p.stdin.close()

View File

@ -68,6 +68,11 @@
;buf LDA LIT "c EQU ;test-x16-cos JCN2
;buf LDA LIT "t EQU ;test-x16-tan JCN2
;buf LDA LIT "l EQU ;test-x16-log JCN2
;buf LDA LIT "F EQU ;test-x16-floor JCN2
;buf LDA LIT "C EQU ;test-x16-ceil JCN2
;buf LDA LIT "R EQU ;test-x16-round JCN2
;buf LDA LIT "T EQU ;test-x16-to-s16 JCN2
;buf LDA LIT "8 EQU ;test-x16-to-s8 JCN2
LIT "? #18 DEO #0a #18 DEO ;reset JSR2 BRK
( set the interpreter to exit now )
@ -93,25 +98,30 @@
( different test executors )
( )
( TEST-NAME #IN #OUT WORD-TO-TEST HARNESS )
@test-x16-add #04 #02 ;x16-add ;test JMP2
@test-x16-mul #04 #02 ;x16-mul ;test JMP2
@test-x16-sub #04 #02 ;x16-sub ;test JMP2
@test-x16-div #04 #02 ;x16-div ;test JMP2
@test-x16-quotient #04 #02 ;x16-quotient ;test JMP2
@test-x16-remainder #04 #02 ;x16-remainder ;test JMP2
@test-x16-is-whole #02 #01 ;x16-is-whole ;test JMP2
@test-x16-negate #02 #02 ;x16-negate ;test JMP2
@test-x16-eq #04 #01 ;x16-eq ;test JMP2
@test-x16-ne #04 #01 ;x16-ne ;test JMP2
@test-x16-lt #04 #01 ;x16-lt ;test JMP2
@test-x16-lteq #04 #01 ;x16-lteq ;test JMP2
@test-x16-gt #04 #01 ;x16-gt ;test JMP2
@test-x16-gteq #04 #01 ;x16-gteq ;test JMP2
@test-x16-sin #02 #02 ;x16-sin ;test JMP2
@test-x16-cos #02 #02 ;x16-cos ;test JMP2
@test-x16-tan #02 #02 ;x16-tan ;test JMP2
@test-x16-log #02 #02 ;x16-log ;test JMP2
( TEST-NAME #IN #OUT WORD-TO-TEST HARNESS )
@test-x16-add #04 #02 ;x16-add ;test JMP2
@test-x16-mul #04 #02 ;x16-mul ;test JMP2
@test-x16-sub #04 #02 ;x16-sub ;test JMP2
@test-x16-div #04 #02 ;x16-div ;test JMP2
@test-x16-quotient #04 #02 ;x16-quotient ;test JMP2
@test-x16-remainder #04 #02 ;x16-remainder ;test JMP2
@test-x16-is-whole #02 #01 ;x16-is-whole ;test JMP2
@test-x16-negate #02 #02 ;x16-negate ;test JMP2
@test-x16-eq #04 #01 ;x16-eq ;test JMP2
@test-x16-ne #04 #01 ;x16-ne ;test JMP2
@test-x16-lt #04 #01 ;x16-lt ;test JMP2
@test-x16-lteq #04 #01 ;x16-lteq ;test JMP2
@test-x16-gt #04 #01 ;x16-gt ;test JMP2
@test-x16-gteq #04 #01 ;x16-gteq ;test JMP2
@test-x16-sin #02 #02 ;x16-sin ;test JMP2
@test-x16-cos #02 #02 ;x16-cos ;test JMP2
@test-x16-tan #02 #02 ;x16-tan ;test JMP2
@test-x16-log #02 #02 ;x16-log ;test JMP2
@test-x16-floor #02 #02 ;x16-floor ;test JMP2
@test-x16-ceil #02 #02 ;x16-ceil ;test JMP2
@test-x16-round #02 #02 ;x16-round ;test JMP2
@test-x16-to-s16 #02 #02 ;x16-to-s16 ;test JMP2
@test-x16-to-s8 #02 #01 ;x16-to-s8 ;test JMP2
( reads one byte from ASCII: "13" -> 0x13 )
@read-byte ( c0^ c1^ -> n^ )