Tentatively manually encoding non-finite f16 values.

Issue #988.
This commit is contained in:
Alex Shinn 2024-06-02 22:31:25 +09:00
parent 3be1603f45
commit d4028f953b
2 changed files with 19 additions and 8 deletions

View file

@ -1,6 +1,6 @@
(define-library (srfi 160 mini-test) (define-library (srfi 160 mini-test)
(import (scheme base) (import (scheme base) (scheme inexact)
(srfi 160 base) (srfi 160 f8) (srfi 160 f16) (srfi 160 base) (srfi 160 f8) (srfi 160 f16)
(chibi test)) (chibi test))
(export run-tests) (export run-tests)
@ -82,7 +82,11 @@
(test '#f16(1 2) (test '#f16(1 2)
(vector->f16vector '#(0 1 2 3) 1 3)) (vector->f16vector '#(0 1 2 3) 1 3))
(test '#(1.0 2.0) (test '#(1.0 2.0)
(f16vector->vector '#f16(0 1 2 3) 1 3)) (f16vector->vector '#f16(0 1 2 3) 1 3))
(test '(-inf.0 -1.0 -0.0 0.0 1.0 +inf.0)
(f16vector->list
'#f16(-inf.0 -1.0 -0.0 0.0 1.0 +inf.0)))
(test-assert (nan? (f16vector-ref '#f16(+nan.0) 0)))
) )
(test-end)))) (test-end))))

19
sexp.c
View file

@ -3206,16 +3206,23 @@ static float int_as_float(const unsigned int n) {
/* https://arxiv.org/abs/2112.08926 */ /* https://arxiv.org/abs/2112.08926 */
double sexp_half_to_double(unsigned short x) { double sexp_half_to_double(unsigned short x) {
unsigned int e = (x&0x7C00)>>10, unsigned int e, m, v;
m = (x&0x03FF)<<13, if (x == 31744) return INFINITY;
v = float_as_int((float)m)>>23; if (x == 32767) return NAN;
if (x == 64512) return -INFINITY;
e = (x&0x7C00)>>10;
m = (x&0x03FF)<<13;
v = float_as_int((float)m)>>23;
return int_as_float((x&0x8000)<<16 | (e!=0)*((e+112)<<23|m) | ((e==0)&(m!=0))*((v-37)<<23|((m<<(150-v))&0x007FE000))); return int_as_float((x&0x8000)<<16 | (e!=0)*((e+112)<<23|m) | ((e==0)&(m!=0))*((v-37)<<23|((m<<(150-v))&0x007FE000)));
} }
unsigned short sexp_double_to_half(double x) { unsigned short sexp_double_to_half(double x) {
unsigned int b = float_as_int(x)+0x00001000, unsigned int b, e, m;
e = (b&0x7F800000)>>23, if (isnan(x)) return 32767;
m = b&0x007FFFFF; if (isinf(x)) return x < 0 ? 64512 : 31744;
b = float_as_int(x)+0x00001000;
e = (b&0x7F800000)>>23;
m = b&0x007FFFFF;
return (b&0x80000000)>>16 | (e>112)*((((e-112)<<10)&0x7C00)|m>>13) | ((e<113)&(e>101))*((((0x007FF000+m)>>(125-e))+1)>>1) | (e>143)*0x7FFF; return (b&0x80000000)>>16 | (e>112)*((((e-112)<<10)&0x7C00)|m>>13) | ((e<113)&(e>101))*((((0x007FF000+m)>>(125-e))+1)>>1) | (e>143)*0x7FFF;
} }
#endif #endif