aboutsummaryrefslogtreecommitdiff
path: root/docs/history/34-ftext/notes.md
blob: 6f0c7ae21738f50822795b03d810e61575722934 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
# 34 — float text

opcode 610 still prints six digits after the dot, and a tie in the next digit still rounds away from zero, so the existing float line does not move. it no longer gives up past about 1e32: the scaled magnitude is a base-2^32 integer, so a finite value prints its digits. `-0` stays `-0.000000`, and a nan is `nan` whatever its sign bit.

opcode 618 (the word 1236) pops `(bits prec mode)`. mode 0 is the shortest spelling that parses back to the same bits: a plain decimal when the exponent is between -4 and 15, otherwise scientific (`1e+308`, `1e-10`, `-0`). mode 1 is fixed, `prec` digits after the dot. mode 2 is scientific, `prec` significant digits. `prec` is capped at 17. print and parse stay out of an o3 region, the same way 610 and 611 do.

the parser keeps the digits of the word it is given (eighty, past that a sticky bit) and converts `significand * 10^exp` with the same integer arithmetic. ties round to even, which is why `9007199254740993` and `9007199254740992` are one double and the next integer is not. `inf`, `-inf`, `nan` and `-nan` are accepted, and an exponent past the double range is an infinity or a zero. nothing here calls libc, so the text does not depend on the host printf. the arm64 jit and llvm call the same C function the interpreter does; the arithmetic opcodes are still native.

`tests/ftext.zc` prints `1e+308 1e-10 -0 inf -inf nan 0.1 1.50 1.250e+0 100000000000000000000.000000 1e+40 1111111111`. the ten ones are bit checks: `1.5` against `3/2`, `0.1` against `1/10`, the infinities, negative zero, the 17-digit tie, a subnormal, an underflow to zero, and a signed nan. the compiler and the runtime were not rebuilt for this; `fops.h` is the whole conversion.

`test.sh` after this stage is 414 passed, 0 failed.