7817
Detour: writing float to stream. In the process I found a bug at the SubX layer X-(
This commit is contained in:
parent
c782d38f0b
commit
a9e0cb7cc9
|
@ -210,6 +210,7 @@ append-byte: # f: (addr stream byte), n: int
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||||
# . save registers
|
# . save registers
|
||||||
|
50/push-eax
|
||||||
51/push-ecx
|
51/push-ecx
|
||||||
57/push-edi
|
57/push-edi
|
||||||
# edi = f
|
# edi = f
|
||||||
|
@ -231,6 +232,7 @@ $append-byte:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5f/pop-to-edi
|
5f/pop-to-edi
|
||||||
59/pop-to-ecx
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
# . epilogue
|
# . epilogue
|
||||||
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
|
|
16
405screen.mu
16
405screen.mu
|
@ -174,15 +174,19 @@ fn print-string screen: (addr screen), s: (addr array byte) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
# fake screen
|
# fake screen
|
||||||
var s2: (stream byte 0x100)
|
var stream-storage: (stream byte 0x100)
|
||||||
var s2-addr/esi: (addr stream byte) <- address s2
|
var stream/esi: (addr stream byte) <- address stream-storage
|
||||||
write s2-addr, s
|
write stream, s
|
||||||
var screen-addr/edi: (addr screen) <- copy screen
|
print-stream screen, stream
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print-stream _screen: (addr screen), s: (addr stream byte) {
|
||||||
|
var screen/edi: (addr screen) <- copy _screen
|
||||||
{
|
{
|
||||||
var done?/eax: boolean <- stream-empty? s2-addr
|
var done?/eax: boolean <- stream-empty? s
|
||||||
compare done?, 0
|
compare done?, 0
|
||||||
break-if-!=
|
break-if-!=
|
||||||
var g/eax: grapheme <- read-grapheme s2-addr
|
var g/eax: grapheme <- read-grapheme s
|
||||||
print-grapheme screen, g
|
print-grapheme screen, g
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,165 +22,165 @@
|
||||||
# This approach turns out to be fast enough for most purposes.
|
# This approach turns out to be fast enough for most purposes.
|
||||||
# Optimizations, however, get wildly more complex.
|
# Optimizations, however, get wildly more complex.
|
||||||
|
|
||||||
fn test-print-float-decimal-approximate-normal {
|
fn test-write-float-decimal-approximate-normal {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 5, 0x20 # 32 columns should be more than enough
|
|
||||||
# 0.5
|
# 0.5
|
||||||
var half/xmm0: float <- rational 1, 2
|
var half/xmm0: float <- rational 1, 2
|
||||||
print-float-decimal-approximate screen, half, 3
|
write-float-decimal-approximate s, half, 3
|
||||||
check-screen-row screen, 1, "0.5 ", "F - test-print-float-decimal-approximate-normal 0.5"
|
check-stream-equal s, "0.5", "F - test-write-float-decimal-approximate-normal 0.5"
|
||||||
# 0.25
|
# 0.25
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var quarter/xmm0: float <- rational 1, 4
|
var quarter/xmm0: float <- rational 1, 4
|
||||||
print-float-decimal-approximate screen, quarter, 3
|
write-float-decimal-approximate s, quarter, 3
|
||||||
check-screen-row screen, 1, "0.25 ", "F - test-print-float-decimal-approximate-normal 0.25"
|
check-stream-equal s, "0.25", "F - test-write-float-decimal-approximate-normal 0.25"
|
||||||
# 0.75
|
# 0.75
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var three-quarters/xmm0: float <- rational 3, 4
|
var three-quarters/xmm0: float <- rational 3, 4
|
||||||
print-float-decimal-approximate screen, three-quarters, 3
|
write-float-decimal-approximate s, three-quarters, 3
|
||||||
check-screen-row screen, 1, "0.75 ", "F - test-print-float-decimal-approximate-normal 0.75"
|
check-stream-equal s, "0.75", "F - test-write-float-decimal-approximate-normal 0.75"
|
||||||
# 0.125
|
# 0.125
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var eighth/xmm0: float <- rational 1, 8
|
var eighth/xmm0: float <- rational 1, 8
|
||||||
print-float-decimal-approximate screen, eighth, 3
|
write-float-decimal-approximate s, eighth, 3
|
||||||
check-screen-row screen, 1, "0.125 ", "F - test-print-float-decimal-approximate-normal 0.125"
|
check-stream-equal s, "0.125", "F - test-write-float-decimal-approximate-normal 0.125"
|
||||||
# 0.0625; start using scientific notation
|
# 0.0625; start using scientific notation
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var sixteenth/xmm0: float <- rational 1, 0x10
|
var sixteenth/xmm0: float <- rational 1, 0x10
|
||||||
print-float-decimal-approximate screen, sixteenth, 3
|
write-float-decimal-approximate s, sixteenth, 3
|
||||||
check-screen-row screen, 1, "6.25e-2 ", "F - test-print-float-decimal-approximate-normal 0.0625"
|
check-stream-equal s, "6.25e-2", "F - test-write-float-decimal-approximate-normal 0.0625"
|
||||||
# sqrt(2); truncate floats with lots of digits after the decimal but not too many before
|
# sqrt(2); truncate floats with lots of digits after the decimal but not too many before
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var two-f/xmm0: float <- rational 2, 1
|
var two-f/xmm0: float <- rational 2, 1
|
||||||
var sqrt-2/xmm0: float <- square-root two-f
|
var sqrt-2/xmm0: float <- square-root two-f
|
||||||
print-float-decimal-approximate screen, sqrt-2, 3
|
write-float-decimal-approximate s, sqrt-2, 3
|
||||||
check-screen-row screen, 1, "1.414 ", "F - test-print-float-decimal-approximate-normal √2"
|
check-stream-equal s, "1.414", "F - test-write-float-decimal-approximate-normal √2"
|
||||||
}
|
}
|
||||||
|
|
||||||
# print whole integers without decimals
|
# print whole integers without decimals
|
||||||
fn test-print-float-decimal-approximate-integer {
|
fn test-write-float-decimal-approximate-integer {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 5, 0x20 # 32 columns should be more than enough
|
|
||||||
# 1
|
# 1
|
||||||
var one-f/xmm0: float <- rational 1, 1
|
var one-f/xmm0: float <- rational 1, 1
|
||||||
print-float-decimal-approximate screen, one-f, 3
|
write-float-decimal-approximate s, one-f, 3
|
||||||
check-screen-row screen, 1, "1 ", "F - test-print-float-decimal-approximate-integer 1"
|
check-stream-equal s, "1", "F - test-write-float-decimal-approximate-integer 1"
|
||||||
# 2
|
# 2
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var two-f/xmm0: float <- rational 2, 1
|
var two-f/xmm0: float <- rational 2, 1
|
||||||
print-float-decimal-approximate screen, two-f, 3
|
write-float-decimal-approximate s, two-f, 3
|
||||||
check-screen-row screen, 1, "2 ", "F - test-print-float-decimal-approximate-integer 2"
|
check-stream-equal s, "2", "F - test-write-float-decimal-approximate-integer 2"
|
||||||
# 10
|
# 10
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var ten-f/xmm0: float <- rational 0xa, 1
|
var ten-f/xmm0: float <- rational 0xa, 1
|
||||||
print-float-decimal-approximate screen, ten-f, 3
|
write-float-decimal-approximate s, ten-f, 3
|
||||||
check-screen-row screen, 1, "10 ", "F - test-print-float-decimal-approximate-integer 10"
|
check-stream-equal s, "10", "F - test-write-float-decimal-approximate-integer 10"
|
||||||
# -10
|
# -10
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var minus-ten-f/xmm0: float <- rational -0xa, 1
|
var minus-ten-f/xmm0: float <- rational -0xa, 1
|
||||||
print-float-decimal-approximate screen, minus-ten-f, 3
|
write-float-decimal-approximate s, minus-ten-f, 3
|
||||||
check-screen-row screen, 1, "-10 ", "F - test-print-float-decimal-approximate-integer -10"
|
check-stream-equal s, "-10", "F - test-write-float-decimal-approximate-integer -10"
|
||||||
# 999
|
# 999
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var minus-ten-f/xmm0: float <- rational 0x3e7, 1
|
var minus-ten-f/xmm0: float <- rational 0x3e7, 1
|
||||||
print-float-decimal-approximate screen, minus-ten-f, 3
|
write-float-decimal-approximate s, minus-ten-f, 3
|
||||||
check-screen-row screen, 1, "999 ", "F - test-print-float-decimal-approximate-integer 1000"
|
check-stream-equal s, "999", "F - test-write-float-decimal-approximate-integer 1000"
|
||||||
# 1000 - start using scientific notation
|
# 1000 - start using scientific notation
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var minus-ten-f/xmm0: float <- rational 0x3e8, 1
|
var minus-ten-f/xmm0: float <- rational 0x3e8, 1
|
||||||
print-float-decimal-approximate screen, minus-ten-f, 3
|
write-float-decimal-approximate s, minus-ten-f, 3
|
||||||
check-screen-row screen, 1, "1.00e3 ", "F - test-print-float-decimal-approximate-integer 1000"
|
check-stream-equal s, "1.00e3", "F - test-write-float-decimal-approximate-integer 1000"
|
||||||
# 100,000
|
# 100,000
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var hundred-thousand/eax: int <- copy 0x186a0
|
var hundred-thousand/eax: int <- copy 0x186a0
|
||||||
var hundred-thousand-f/xmm0: float <- convert hundred-thousand
|
var hundred-thousand-f/xmm0: float <- convert hundred-thousand
|
||||||
print-float-decimal-approximate screen, hundred-thousand-f, 3
|
write-float-decimal-approximate s, hundred-thousand-f, 3
|
||||||
check-screen-row screen, 1, "1.00e5 ", "F - test-print-float-decimal-approximate-integer 100,000"
|
check-stream-equal s, "1.00e5", "F - test-write-float-decimal-approximate-integer 100,000"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-print-float-decimal-approximate-zero {
|
fn test-write-float-decimal-approximate-zero {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 5, 0x20 # 32 columns should be more than enough
|
|
||||||
var zero: float
|
var zero: float
|
||||||
print-float-decimal-approximate screen, zero, 3
|
write-float-decimal-approximate s, zero, 3
|
||||||
check-screen-row screen, 1, "0 ", "F - test-print-float-decimal-approximate-zero"
|
check-stream-equal s, "0", "F - test-write-float-decimal-approximate-zero"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-print-float-decimal-approximate-negative-zero {
|
fn test-write-float-decimal-approximate-negative-zero {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 5, 0x20 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
copy-to n, 0x80000000
|
copy-to n, 0x80000000
|
||||||
var negative-zero/xmm0: float <- reinterpret n
|
var negative-zero/xmm0: float <- reinterpret n
|
||||||
print-float-decimal-approximate screen, negative-zero, 3
|
write-float-decimal-approximate s, negative-zero, 3
|
||||||
check-screen-row screen, 1, "-0 ", "F - test-print-float-decimal-approximate-negative-zero"
|
check-stream-equal s, "-0", "F - test-write-float-decimal-approximate-negative-zero"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-print-float-decimal-approximate-infinity {
|
fn test-write-float-decimal-approximate-infinity {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 5, 0x20 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
# 0|11111111|00000000000000000000000
|
# 0|11111111|00000000000000000000000
|
||||||
# 0111|1111|1000|0000|0000|0000|0000|0000
|
# 0111|1111|1000|0000|0000|0000|0000|0000
|
||||||
copy-to n, 0x7f800000
|
copy-to n, 0x7f800000
|
||||||
var infinity/xmm0: float <- reinterpret n
|
var infinity/xmm0: float <- reinterpret n
|
||||||
print-float-decimal-approximate screen, infinity, 3
|
write-float-decimal-approximate s, infinity, 3
|
||||||
check-screen-row screen, 1, "Inf ", "F - test-print-float-decimal-approximate-infinity"
|
check-stream-equal s, "Inf", "F - test-write-float-decimal-approximate-infinity"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-print-float-decimal-approximate-negative-infinity {
|
fn test-write-float-decimal-approximate-negative-infinity {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 5, 0x20 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
copy-to n, 0xff800000
|
copy-to n, 0xff800000
|
||||||
var negative-infinity/xmm0: float <- reinterpret n
|
var negative-infinity/xmm0: float <- reinterpret n
|
||||||
print-float-decimal-approximate screen, negative-infinity, 3
|
write-float-decimal-approximate s, negative-infinity, 3
|
||||||
check-screen-row screen, 1, "-Inf ", "F - test-print-float-decimal-approximate-negative-infinity"
|
check-stream-equal s, "-Inf", "F - test-write-float-decimal-approximate-negative-infinity"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-print-float-decimal-approximate-not-a-number {
|
fn test-write-float-decimal-approximate-not-a-number {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 5, 0x20 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
copy-to n, 0xffffffff # exponent must be all 1's, and mantissa must be non-zero
|
copy-to n, 0xffffffff # exponent must be all 1's, and mantissa must be non-zero
|
||||||
var nan/xmm0: float <- reinterpret n
|
var nan/xmm0: float <- reinterpret n
|
||||||
print-float-decimal-approximate screen, nan, 3
|
write-float-decimal-approximate s, nan, 3
|
||||||
check-screen-row screen, 1, "NaN ", "F - test-print-float-decimal-approximate-not-a-number"
|
check-stream-equal s, "NaN", "F - test-write-float-decimal-approximate-not-a-number"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print-float-decimal-approximate screen: (addr screen), in: float, precision: int {
|
||||||
|
var s-storage: (stream byte 0x10)
|
||||||
|
var s/esi: (addr stream byte) <- address s-storage
|
||||||
|
write-float-decimal-approximate s, in, precision
|
||||||
|
print-stream screen, s
|
||||||
}
|
}
|
||||||
|
|
||||||
# 'precision' controls the maximum width past which we resort to scientific notation
|
# 'precision' controls the maximum width past which we resort to scientific notation
|
||||||
fn print-float-decimal-approximate screen: (addr screen), in: float, precision: int {
|
fn write-float-decimal-approximate out: (addr stream byte), in: float, precision: int {
|
||||||
# - special names
|
# - special names
|
||||||
var bits/eax: int <- reinterpret in
|
var bits/eax: int <- reinterpret in
|
||||||
compare bits, 0
|
compare bits, 0
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "0"
|
write out, "0"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
compare bits, 0x80000000
|
compare bits, 0x80000000
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "-0"
|
write out, "-0"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
compare bits, 0x7f800000
|
compare bits, 0x7f800000
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "Inf"
|
write out, "Inf"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
compare bits, 0xff800000
|
compare bits, 0xff800000
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "-Inf"
|
write out, "-Inf"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var exponent/ecx: int <- copy bits
|
var exponent/ecx: int <- copy bits
|
||||||
|
@ -190,7 +190,7 @@ fn print-float-decimal-approximate screen: (addr screen), in: float, precision:
|
||||||
compare exponent, 0x80
|
compare exponent, 0x80
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "NaN"
|
write out, "NaN"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
# - regular numbers
|
# - regular numbers
|
||||||
|
@ -199,7 +199,7 @@ fn print-float-decimal-approximate screen: (addr screen), in: float, precision:
|
||||||
{
|
{
|
||||||
compare sign, 1
|
compare sign, 1
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "-"
|
append-byte out, 0x2d/minus
|
||||||
}
|
}
|
||||||
|
|
||||||
# v = 1.mantissa (in base 2) << 0x17
|
# v = 1.mantissa (in base 2) << 0x17
|
||||||
|
@ -239,7 +239,7 @@ fn print-float-decimal-approximate screen: (addr screen), in: float, precision:
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
|
|
||||||
print-float-buffer screen, buf, n, dp, precision
|
_write-float-array-of-decimal-digits out, buf, n, dp, precision
|
||||||
}
|
}
|
||||||
|
|
||||||
# store the decimal digits of 'n' into 'buf', units first
|
# store the decimal digits of 'n' into 'buf', units first
|
||||||
|
@ -429,27 +429,25 @@ fn halve-array-of-decimal-digits _buf: (addr array byte), _n: int, _dp: int -> _
|
||||||
return n, dp
|
return n, dp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print-float-buffer screen: (addr screen), _buf: (addr array byte), n: int, dp: int, precision: int {
|
fn _write-float-array-of-decimal-digits out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int {
|
||||||
var buf/edi: (addr array byte) <- copy _buf
|
var buf/edi: (addr array byte) <- copy _buf
|
||||||
#? print-int32-hex 0, dp
|
|
||||||
#? print-string 0, "\n"
|
|
||||||
{
|
{
|
||||||
compare dp, 0
|
compare dp, 0
|
||||||
break-if->=
|
break-if->=
|
||||||
print-float-buffer-in-scientific-notation screen, buf, n, dp, precision
|
_write-float-array-of-decimal-digits-in-scientific-notation out, buf, n, dp, precision
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var dp2/eax: int <- copy dp
|
var dp2/eax: int <- copy dp
|
||||||
compare dp2, precision
|
compare dp2, precision
|
||||||
break-if-<=
|
break-if-<=
|
||||||
print-float-buffer-in-scientific-notation screen, buf, n, dp, precision
|
_write-float-array-of-decimal-digits-in-scientific-notation out, buf, n, dp, precision
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
compare dp, 0
|
compare dp, 0
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "0"
|
append-byte out, 0x30/0
|
||||||
}
|
}
|
||||||
var i/eax: int <- copy 0
|
var i/eax: int <- copy 0
|
||||||
# bounds = min(n, dp+3)
|
# bounds = min(n, dp+3)
|
||||||
|
@ -467,19 +465,20 @@ fn print-float-buffer screen: (addr screen), _buf: (addr array byte), n: int, dp
|
||||||
compare i, dp
|
compare i, dp
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "."
|
append-byte out, 0x2e/decimal-point
|
||||||
}
|
}
|
||||||
var curr-a/ecx: (addr byte) <- index buf, i
|
var curr-a/ecx: (addr byte) <- index buf, i
|
||||||
var curr/ecx: byte <- copy-byte *curr-a
|
var curr/ecx: byte <- copy-byte *curr-a
|
||||||
curr <- add 0x30/0
|
var curr-int/ecx: int <- copy curr
|
||||||
var curr-grapheme/ecx: grapheme <- copy curr
|
curr-int <- add 0x30/0
|
||||||
print-grapheme screen, curr-grapheme
|
append-byte out, curr-int
|
||||||
|
#
|
||||||
i <- increment
|
i <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print-float-buffer-in-scientific-notation screen: (addr screen), _buf: (addr array byte), n: int, dp: int, precision: int {
|
fn _write-float-array-of-decimal-digits-in-scientific-notation out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int {
|
||||||
var buf/edi: (addr array byte) <- copy _buf
|
var buf/edi: (addr array byte) <- copy _buf
|
||||||
var i/eax: int <- copy 0
|
var i/eax: int <- copy 0
|
||||||
{
|
{
|
||||||
|
@ -490,23 +489,23 @@ fn print-float-buffer-in-scientific-notation screen: (addr screen), _buf: (addr
|
||||||
compare i, 1
|
compare i, 1
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
print-string screen, "."
|
append-byte out, 0x2e/decimal-point
|
||||||
}
|
}
|
||||||
var curr-a/ecx: (addr byte) <- index buf, i
|
var curr-a/ecx: (addr byte) <- index buf, i
|
||||||
var curr/ecx: byte <- copy-byte *curr-a
|
var curr/ecx: byte <- copy-byte *curr-a
|
||||||
curr <- add 0x30/0
|
var curr-int/ecx: int <- copy curr
|
||||||
var curr-grapheme/ecx: grapheme <- copy curr
|
curr-int <- add 0x30/0
|
||||||
print-grapheme screen, curr-grapheme
|
append-byte out, curr-int
|
||||||
#
|
#
|
||||||
i <- increment
|
i <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
print-string screen, "e"
|
append-byte out, 0x65/e
|
||||||
decrement dp
|
decrement dp
|
||||||
print-int32-decimal screen, dp
|
write-int32-decimal out, dp
|
||||||
}
|
}
|
||||||
|
|
||||||
# follows the structure of print-float-decimal-approximate
|
# follows the structure of write-float-decimal-approximate
|
||||||
# 'precision' controls the maximum width past which we resort to scientific notation
|
# 'precision' controls the maximum width past which we resort to scientific notation
|
||||||
fn float-size in: float, precision: int -> _/eax: int {
|
fn float-size in: float, precision: int -> _/eax: int {
|
||||||
# - special names
|
# - special names
|
||||||
|
@ -641,10 +640,3 @@ fn test-check-buffer-contains {
|
||||||
check-buffer-contains a, "a", "F - test-check-buffer-contains"
|
check-buffer-contains a, "a", "F - test-check-buffer-contains"
|
||||||
check-buffer-contains "a", "a", "F - test-check-buffer-contains/null" # no null check when arrays have same length
|
check-buffer-contains "a", "a", "F - test-check-buffer-contains/null" # no null check when arrays have same length
|
||||||
}
|
}
|
||||||
|
|
||||||
#? fn main -> _/ebx: int {
|
|
||||||
#? run-tests
|
|
||||||
#? #? test-print-float-decimal-approximate-integer
|
|
||||||
#? #? test-print-float-decimal-approximate-normal
|
|
||||||
#? return 0
|
|
||||||
#? }
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ append-byte: # f: (addr stream byte), n: int
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||||
# . save registers
|
# . save registers
|
||||||
|
50/push-eax
|
||||||
51/push-ecx
|
51/push-ecx
|
||||||
57/push-edi
|
57/push-edi
|
||||||
# edi = f
|
# edi = f
|
||||||
|
@ -35,6 +36,7 @@ $append-byte:end:
|
||||||
# . restore registers
|
# . restore registers
|
||||||
5f/pop-to-edi
|
5f/pop-to-edi
|
||||||
59/pop-to-ecx
|
59/pop-to-ecx
|
||||||
|
58/pop-to-eax
|
||||||
# . epilogue
|
# . epilogue
|
||||||
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
|
|
|
@ -22,166 +22,170 @@
|
||||||
# This approach turns out to be fast enough for most purposes.
|
# This approach turns out to be fast enough for most purposes.
|
||||||
# Optimizations, however, get wildly more complex.
|
# Optimizations, however, get wildly more complex.
|
||||||
|
|
||||||
fn test-render-float-decimal-normal {
|
fn test-write-float-decimal-approximate-normal {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 0x20, 5 # 32 columns should be more than enough
|
|
||||||
# 0.5
|
# 0.5
|
||||||
var half/xmm0: float <- rational 1, 2
|
var half/xmm0: float <- rational 1, 2
|
||||||
var dummy/eax: int <- render-float-decimal screen, half, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, half, 3
|
||||||
check-screen-row screen, 0/y, "0.5 ", "F - test-render-float-decimal-normal 0.5"
|
check-stream-equal s, "0.5", "F - test-write-float-decimal-approximate-normal 0.5"
|
||||||
# 0.25
|
# 0.25
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var quarter/xmm0: float <- rational 1, 4
|
var quarter/xmm0: float <- rational 1, 4
|
||||||
var dummy/eax: int <- render-float-decimal screen, quarter, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, quarter, 3
|
||||||
check-screen-row screen, 0/y, "0.25 ", "F - test-render-float-decimal-normal 0.25"
|
check-stream-equal s, "0.25", "F - test-write-float-decimal-approximate-normal 0.25"
|
||||||
# 0.75
|
# 0.75
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var three-quarters/xmm0: float <- rational 3, 4
|
var three-quarters/xmm0: float <- rational 3, 4
|
||||||
var dummy/eax: int <- render-float-decimal screen, three-quarters, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, three-quarters, 3
|
||||||
check-screen-row screen, 0/y, "0.75 ", "F - test-render-float-decimal-normal 0.75"
|
check-stream-equal s, "0.75", "F - test-write-float-decimal-approximate-normal 0.75"
|
||||||
# 0.125
|
# 0.125
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var eighth/xmm0: float <- rational 1, 8
|
var eighth/xmm0: float <- rational 1, 8
|
||||||
var dummy/eax: int <- render-float-decimal screen, eighth, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, eighth, 3
|
||||||
check-screen-row screen, 0/y, "0.125 ", "F - test-render-float-decimal-normal 0.125"
|
check-stream-equal s, "0.125", "F - test-write-float-decimal-approximate-normal 0.125"
|
||||||
# 0.0625; start using scientific notation
|
# 0.0625; start using scientific notation
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var sixteenth/xmm0: float <- rational 1, 0x10
|
var sixteenth/xmm0: float <- rational 1, 0x10
|
||||||
var dummy/eax: int <- render-float-decimal screen, sixteenth, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, sixteenth, 3
|
||||||
check-screen-row screen, 0/y, "6.25e-2 ", "F - test-render-float-decimal-normal 0.0625"
|
check-stream-equal s, "6.25e-2", "F - test-write-float-decimal-approximate-normal 0.0625"
|
||||||
# sqrt(2); truncate floats with lots of digits after the decimal but not too many before
|
# sqrt(2); truncate floats with lots of digits after the decimal but not too many before
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var two-f/xmm0: float <- rational 2, 1
|
var two-f/xmm0: float <- rational 2, 1
|
||||||
var sqrt-2/xmm0: float <- square-root two-f
|
var sqrt-2/xmm0: float <- square-root two-f
|
||||||
var dummy/eax: int <- render-float-decimal screen, sqrt-2, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, sqrt-2, 3
|
||||||
check-screen-row screen, 0/y, "1.414 ", "F - test-render-float-decimal-normal √2"
|
check-stream-equal s, "1.414", "F - test-write-float-decimal-approximate-normal √2"
|
||||||
}
|
}
|
||||||
|
|
||||||
# print whole integers without decimals
|
# print whole integers without decimals
|
||||||
fn test-render-float-decimal-integer {
|
fn test-write-float-decimal-approximate-integer {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 0x20, 5 # 32 columns should be more than enough
|
|
||||||
# 1
|
# 1
|
||||||
var one-f/xmm0: float <- rational 1, 1
|
var one-f/xmm0: float <- rational 1, 1
|
||||||
var dummy/eax: int <- render-float-decimal screen, one-f, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, one-f, 3
|
||||||
check-screen-row screen, 0/y, "1 ", "F - test-render-float-decimal-integer 1"
|
check-stream-equal s, "1", "F - test-write-float-decimal-approximate-integer 1"
|
||||||
# 2
|
# 2
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var two-f/xmm0: float <- rational 2, 1
|
var two-f/xmm0: float <- rational 2, 1
|
||||||
var dummy/eax: int <- render-float-decimal screen, two-f, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, two-f, 3
|
||||||
check-screen-row screen, 0/y, "2 ", "F - test-render-float-decimal-integer 2"
|
check-stream-equal s, "2", "F - test-write-float-decimal-approximate-integer 2"
|
||||||
# 10
|
# 10
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var ten-f/xmm0: float <- rational 0xa, 1
|
var ten-f/xmm0: float <- rational 0xa, 1
|
||||||
var dummy/eax: int <- render-float-decimal screen, ten-f, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, ten-f, 3
|
||||||
check-screen-row screen, 0/y, "10 ", "F - test-render-float-decimal-integer 10"
|
check-stream-equal s, "10", "F - test-write-float-decimal-approximate-integer 10"
|
||||||
# -10
|
# -10
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var minus-ten-f/xmm0: float <- rational -0xa, 1
|
var minus-ten-f/xmm0: float <- rational -0xa, 1
|
||||||
var dummy/eax: int <- render-float-decimal screen, minus-ten-f, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, minus-ten-f, 3
|
||||||
check-screen-row screen, 0/y, "-10 ", "F - test-render-float-decimal-integer -10"
|
check-stream-equal s, "-10", "F - test-write-float-decimal-approximate-integer -10"
|
||||||
# 999
|
# 999
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var minus-ten-f/xmm0: float <- rational 0x3e7, 1
|
var minus-ten-f/xmm0: float <- rational 0x3e7, 1
|
||||||
var dummy/eax: int <- render-float-decimal screen, minus-ten-f, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, minus-ten-f, 3
|
||||||
check-screen-row screen, 0/y, "999 ", "F - test-render-float-decimal-integer 1000"
|
check-stream-equal s, "999", "F - test-write-float-decimal-approximate-integer 1000"
|
||||||
# 1000 - start using scientific notation
|
# 1000 - start using scientific notation
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var minus-ten-f/xmm0: float <- rational 0x3e8, 1
|
var minus-ten-f/xmm0: float <- rational 0x3e8, 1
|
||||||
var dummy/eax: int <- render-float-decimal screen, minus-ten-f, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, minus-ten-f, 3
|
||||||
check-screen-row screen, 0/y, "1.00e3 ", "F - test-render-float-decimal-integer 1000"
|
check-stream-equal s, "1.00e3", "F - test-write-float-decimal-approximate-integer 1000"
|
||||||
# 100,000
|
# 100,000
|
||||||
clear-screen screen
|
clear-stream s
|
||||||
var hundred-thousand/eax: int <- copy 0x186a0
|
var hundred-thousand/eax: int <- copy 0x186a0
|
||||||
var hundred-thousand-f/xmm0: float <- convert hundred-thousand
|
var hundred-thousand-f/xmm0: float <- convert hundred-thousand
|
||||||
var dummy/eax: int <- render-float-decimal screen, hundred-thousand-f, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, hundred-thousand-f, 3
|
||||||
check-screen-row screen, 0/y, "1.00e5 ", "F - test-render-float-decimal-integer 100,000"
|
check-stream-equal s, "1.00e5", "F - test-write-float-decimal-approximate-integer 100,000"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-render-float-decimal-zero {
|
fn test-write-float-decimal-approximate-zero {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 0x20, 5 # 32 columns should be more than enough
|
|
||||||
var zero: float
|
var zero: float
|
||||||
var dummy/eax: int <- render-float-decimal screen, zero, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, zero, 3
|
||||||
check-screen-row screen, 0/y, "0 ", "F - test-render-float-decimal-zero"
|
check-stream-equal s, "0", "F - test-write-float-decimal-approximate-zero"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-render-float-decimal-negative-zero {
|
fn test-write-float-decimal-approximate-negative-zero {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 0x20, 5 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
copy-to n, 0x80000000
|
copy-to n, 0x80000000
|
||||||
var negative-zero/xmm0: float <- reinterpret n
|
var negative-zero/xmm0: float <- reinterpret n
|
||||||
var dummy/eax: int <- render-float-decimal screen, negative-zero, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, negative-zero, 3
|
||||||
check-screen-row screen, 0/y, "-0 ", "F - test-render-float-decimal-negative-zero"
|
check-stream-equal s, "-0", "F - test-write-float-decimal-approximate-negative-zero"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-render-float-decimal-infinity {
|
fn test-write-float-decimal-approximate-infinity {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 0x20, 5 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
# 0|11111111|00000000000000000000000
|
# 0|11111111|00000000000000000000000
|
||||||
# 0111|1111|1000|0000|0000|0000|0000|0000
|
# 0111|1111|1000|0000|0000|0000|0000|0000
|
||||||
copy-to n, 0x7f800000
|
copy-to n, 0x7f800000
|
||||||
var infinity/xmm0: float <- reinterpret n
|
var infinity/xmm0: float <- reinterpret n
|
||||||
var dummy/eax: int <- render-float-decimal screen, infinity, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, infinity, 3
|
||||||
check-screen-row screen, 0/y, "Inf ", "F - test-render-float-decimal-infinity"
|
check-stream-equal s, "Inf", "F - test-write-float-decimal-approximate-infinity"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-render-float-decimal-negative-infinity {
|
fn test-write-float-decimal-approximate-negative-infinity {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 0x20, 5 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
copy-to n, 0xff800000
|
copy-to n, 0xff800000
|
||||||
var negative-infinity/xmm0: float <- reinterpret n
|
var negative-infinity/xmm0: float <- reinterpret n
|
||||||
var dummy/eax: int <- render-float-decimal screen, negative-infinity, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, negative-infinity, 3
|
||||||
check-screen-row screen, 0/y, "-Inf ", "F - test-render-float-decimal-negative-infinity"
|
check-stream-equal s, "-Inf", "F - test-write-float-decimal-approximate-negative-infinity"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test-render-float-decimal-not-a-number {
|
fn test-write-float-decimal-approximate-not-a-number {
|
||||||
var screen-on-stack: screen
|
var s-storage: (stream byte 0x10)
|
||||||
var screen/esi: (addr screen) <- address screen-on-stack
|
var s/ecx: (addr stream byte) <- address s-storage
|
||||||
initialize-screen screen, 0x20, 5 # 32 columns should be more than enough
|
|
||||||
var n: int
|
var n: int
|
||||||
copy-to n, 0xffffffff # exponent must be all 1's, and mantissa must be non-zero
|
copy-to n, 0xffffffff # exponent must be all 1's, and mantissa must be non-zero
|
||||||
var nan/xmm0: float <- reinterpret n
|
var nan/xmm0: float <- reinterpret n
|
||||||
var dummy/eax: int <- render-float-decimal screen, nan, 3/precision, 0, 0, 3/fg, 0/bg
|
write-float-decimal-approximate s, nan, 3
|
||||||
check-screen-row screen, 0/y, "NaN ", "F - test-render-float-decimal-not-a-number"
|
check-stream-equal s, "NaN", "F - test-write-float-decimal-approximate-not-a-number"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render-float-decimal screen: (addr screen), in: float, precision: int, x: int, y: int, color: int, background-color: int -> _/eax: int {
|
||||||
|
var s-storage: (stream byte 0x10)
|
||||||
|
var s/esi: (addr stream byte) <- address s-storage
|
||||||
|
write-float-decimal-approximate s, in, precision
|
||||||
|
var width/eax: int <- copy 0
|
||||||
|
var height/ecx: int <- copy 0
|
||||||
|
width, height <- screen-size screen
|
||||||
|
var result/eax: int <- draw-stream-rightward screen, s, x, width, y, color, background-color
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
# 'precision' controls the maximum width past which we resort to scientific notation
|
# 'precision' controls the maximum width past which we resort to scientific notation
|
||||||
fn render-float-decimal screen: (addr screen), in: float, precision: int, x: int, y: int, color: int, background-color: int -> _/eax: int {
|
fn write-float-decimal-approximate out: (addr stream byte), in: float, precision: int {
|
||||||
# - special names
|
# - special names
|
||||||
var bits/eax: int <- reinterpret in
|
var bits/eax: int <- reinterpret in
|
||||||
compare bits, 0
|
compare bits, 0
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
var new-x/eax: int <- draw-text-rightward-over-full-screen screen, "0", x, y, color, background-color
|
write out, "0"
|
||||||
return new-x
|
return
|
||||||
}
|
}
|
||||||
compare bits, 0x80000000
|
compare bits, 0x80000000
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
var new-x/eax: int <- draw-text-rightward-over-full-screen screen, "-0", x, y, color, background-color
|
write out, "-0"
|
||||||
return new-x
|
return
|
||||||
}
|
}
|
||||||
compare bits, 0x7f800000
|
compare bits, 0x7f800000
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
var new-x/eax: int <- draw-text-rightward-over-full-screen screen, "Inf", x, y, color, background-color
|
write out, "Inf"
|
||||||
return new-x
|
return
|
||||||
}
|
}
|
||||||
compare bits, 0xff800000
|
compare bits, 0xff800000
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
var new-x/eax: int <- draw-text-rightward-over-full-screen screen, "-Inf", x, y, color, background-color
|
write out, "-Inf"
|
||||||
return new-x
|
return
|
||||||
}
|
}
|
||||||
var exponent/ecx: int <- copy bits
|
var exponent/ecx: int <- copy bits
|
||||||
exponent <- shift-right 0x17 # 23 bits of mantissa
|
exponent <- shift-right 0x17 # 23 bits of mantissa
|
||||||
|
@ -190,8 +194,8 @@ fn render-float-decimal screen: (addr screen), in: float, precision: int, x: int
|
||||||
compare exponent, 0x80
|
compare exponent, 0x80
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
var new-x/eax: int <- draw-text-rightward-over-full-screen screen, "NaN", x, y, color, background-color
|
write out, "NaN"
|
||||||
return new-x
|
return
|
||||||
}
|
}
|
||||||
# - regular numbers
|
# - regular numbers
|
||||||
var sign/edx: int <- copy bits
|
var sign/edx: int <- copy bits
|
||||||
|
@ -199,8 +203,7 @@ fn render-float-decimal screen: (addr screen), in: float, precision: int, x: int
|
||||||
{
|
{
|
||||||
compare sign, 1
|
compare sign, 1
|
||||||
break-if-!=
|
break-if-!=
|
||||||
draw-code-point screen, 0x2d/minus, x, y, color, background-color
|
append-byte out, 0x2d/minus
|
||||||
increment x
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# v = 1.mantissa (in base 2) << 0x17
|
# v = 1.mantissa (in base 2) << 0x17
|
||||||
|
@ -240,8 +243,7 @@ fn render-float-decimal screen: (addr screen), in: float, precision: int, x: int
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
|
|
||||||
var new-x/eax: int <- render-float-buffer screen, buf, n, dp, precision, x, y, color, background-color
|
_write-float-array-of-decimal-digits out, buf, n, dp, precision
|
||||||
return new-x
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# store the decimal digits of 'n' into 'buf', units first
|
# store the decimal digits of 'n' into 'buf', units first
|
||||||
|
@ -410,26 +412,25 @@ fn halve-array-of-decimal-digits _buf: (addr array byte), _n: int, _dp: int -> _
|
||||||
return n, dp
|
return n, dp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render-float-buffer screen: (addr screen), _buf: (addr array byte), n: int, dp: int, precision: int, x: int, y: int, color: int, background-color: int -> _/eax: int {
|
fn _write-float-array-of-decimal-digits out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int {
|
||||||
var buf/edi: (addr array byte) <- copy _buf
|
var buf/edi: (addr array byte) <- copy _buf
|
||||||
{
|
{
|
||||||
compare dp, 0
|
compare dp, 0
|
||||||
break-if->=
|
break-if->=
|
||||||
var new-x/eax: int <- render-float-buffer-in-scientific-notation screen, buf, n, dp, precision, x, y, color, background-color
|
_write-float-array-of-decimal-digits-in-scientific-notation out, buf, n, dp, precision
|
||||||
return new-x
|
return
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var dp2/eax: int <- copy dp
|
var dp2/eax: int <- copy dp
|
||||||
compare dp2, precision
|
compare dp2, precision
|
||||||
break-if-<=
|
break-if-<=
|
||||||
var new-x/eax: int <- render-float-buffer-in-scientific-notation screen, buf, n, dp, precision, x, y, color, background-color
|
_write-float-array-of-decimal-digits-in-scientific-notation out, buf, n, dp, precision
|
||||||
return new-x
|
return
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
compare dp, 0
|
compare dp, 0
|
||||||
break-if-!=
|
break-if-!=
|
||||||
draw-code-point screen, 0x30/0, x, y, color, background-color
|
append-byte out, 0x30/0
|
||||||
increment x
|
|
||||||
}
|
}
|
||||||
var i/eax: int <- copy 0
|
var i/eax: int <- copy 0
|
||||||
# bounds = min(n, dp+3)
|
# bounds = min(n, dp+3)
|
||||||
|
@ -447,22 +448,20 @@ fn render-float-buffer screen: (addr screen), _buf: (addr array byte), n: int, d
|
||||||
compare i, dp
|
compare i, dp
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
draw-code-point screen, 0x2e/decimal-point, x, y, color, background-color
|
append-byte out, 0x2e/decimal-point
|
||||||
increment x
|
|
||||||
}
|
}
|
||||||
var curr-a/ecx: (addr byte) <- index buf, i
|
var curr-a/ecx: (addr byte) <- index buf, i
|
||||||
var curr/ecx: byte <- copy-byte *curr-a
|
var curr/ecx: byte <- copy-byte *curr-a
|
||||||
curr <- add 0x30/0
|
var curr-int/ecx: int <- copy curr
|
||||||
var curr-grapheme/ecx: grapheme <- copy curr
|
curr-int <- add 0x30/0
|
||||||
draw-grapheme screen, curr-grapheme, x, y, color, background-color
|
append-byte out, curr-int
|
||||||
increment x
|
#
|
||||||
i <- increment
|
i <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
return x
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render-float-buffer-in-scientific-notation screen: (addr screen), _buf: (addr array byte), n: int, dp: int, precision: int, x: int, y: int, color: int, background-color: int -> _/eax: int {
|
fn _write-float-array-of-decimal-digits-in-scientific-notation out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int {
|
||||||
var buf/edi: (addr array byte) <- copy _buf
|
var buf/edi: (addr array byte) <- copy _buf
|
||||||
var i/eax: int <- copy 0
|
var i/eax: int <- copy 0
|
||||||
{
|
{
|
||||||
|
@ -473,29 +472,23 @@ fn render-float-buffer-in-scientific-notation screen: (addr screen), _buf: (addr
|
||||||
compare i, 1
|
compare i, 1
|
||||||
{
|
{
|
||||||
break-if-!=
|
break-if-!=
|
||||||
draw-code-point screen, 0x2e/decimal-point, x, y, color, background-color
|
append-byte out, 0x2e/decimal-point
|
||||||
increment x
|
|
||||||
}
|
}
|
||||||
var curr-a/ecx: (addr byte) <- index buf, i
|
var curr-a/ecx: (addr byte) <- index buf, i
|
||||||
var curr/ecx: byte <- copy-byte *curr-a
|
var curr/ecx: byte <- copy-byte *curr-a
|
||||||
curr <- add 0x30/0
|
var curr-int/ecx: int <- copy curr
|
||||||
var curr-grapheme/ecx: grapheme <- copy curr
|
curr-int <- add 0x30/0
|
||||||
draw-grapheme screen, curr-grapheme, x, y, color, background-color
|
append-byte out, curr-int
|
||||||
increment x
|
|
||||||
#
|
#
|
||||||
i <- increment
|
i <- increment
|
||||||
loop
|
loop
|
||||||
}
|
}
|
||||||
draw-code-point screen, 0x65/e, x, y, color, background-color
|
append-byte out, 0x65/e
|
||||||
increment x
|
|
||||||
decrement dp
|
decrement dp
|
||||||
var new-x/eax: int <- copy 0
|
write-int32-decimal out, dp
|
||||||
var new-y/ecx: int <- copy 0
|
|
||||||
new-x, new-y <- draw-int32-decimal-wrapping-right-then-down-over-full-screen screen, dp, x, y, color, background-color
|
|
||||||
return new-x
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# follows the structure of render-float-decimal
|
# follows the structure of write-float-decimal-approximate
|
||||||
# 'precision' controls the maximum width past which we resort to scientific notation
|
# 'precision' controls the maximum width past which we resort to scientific notation
|
||||||
fn float-size in: float, precision: int -> _/eax: int {
|
fn float-size in: float, precision: int -> _/eax: int {
|
||||||
# - special names
|
# - special names
|
||||||
|
|
Loading…
Reference in New Issue