76
76
// FLOAT16 credits: Steven Pigeon
77
77
// https://hbfs.wordpress.com/2013/02/12/float16/
78
78
typedef union {
79
- // float16 v;
80
79
struct {
81
80
// type determines alignment!
82
81
u16 m : 10 ;
@@ -101,12 +100,21 @@ typedef union {
101
100
float float16to32 (float16_s f16 ) {
102
101
// back to 32
103
102
float32_s f32 ;
103
+ #ifndef USE_NO_INFINITY
104
+ if (f16 .bits .e == 31 ) { // inifinity or nan
105
+ return (f16 .bits .m == 0 ) ? (f16 .bits .s ? -1.0 : 1.0 ) * INFINITY : NAN ;
106
+ }
107
+ #endif
104
108
f32 .bits .s = f16 .bits .s ;
105
109
f32 .bits .e = (f16 .bits .e - 15 ) + 127 ; // safe in this direction
106
110
f32 .bits .m = ((u32 )f16 .bits .m ) << 13 ;
107
111
return f32 .v ;
108
112
}
109
113
114
+ //float float64to16(float16_s f16) {
115
+ // half s;
116
+ //}
117
+
110
118
#pragma pack(4)
111
119
typedef union {
112
120
u16 num ;
@@ -233,10 +241,16 @@ static REBCNT EncodedU32_Size(u32 value) {
233
241
REBCNT inBit , nbits ;
234
242
REBYTE * cp , * bp , * ep ;
235
243
REBCNT n , count , index , tail , tail_new ;
244
+ REBDEC dbl ;
245
+ REBD32 d32 ;
236
246
i32 i , len ;
237
247
u64 u ;
238
248
i64 si ;
239
249
u32 ulong ;
250
+ u16 ushort ;
251
+ float16_s f16 ;
252
+ float32_s f32 ;
253
+
240
254
241
255
ms_datetime * msdt = NULL ;
242
256
ms_date * msd = NULL ;
@@ -502,7 +516,26 @@ static REBCNT EncodedU32_Size(u32 value) {
502
516
continue ;
503
517
}
504
518
goto error ;
505
-
519
+
520
+ case SYM_FLOAT :
521
+ if (IS_INTEGER (next ) || IS_DECIMAL (next )) {
522
+ count += 4 ;
523
+ continue ;
524
+ }
525
+ goto error ;
526
+ case SYM_DOUBLE :
527
+ if (IS_INTEGER (next ) || IS_DECIMAL (next )) {
528
+ count += 8 ;
529
+ continue ;
530
+ }
531
+ goto error ;
532
+ case SYM_FLOAT16 :
533
+ if (IS_INTEGER (next ) || IS_DECIMAL (next )) {
534
+ count += 2 ;
535
+ continue ;
536
+ }
537
+ goto error ;
538
+
506
539
case SYM_UNIXTIME_NOW :
507
540
case SYM_UNIXTIME_NOW_LE :
508
541
value -- ; //there is no argument so no next
@@ -762,6 +795,41 @@ static REBCNT EncodedU32_Size(u32 value) {
762
795
memcpy (cp , VAL_BIN_AT (next ), n );
763
796
VAL_INDEX (buffer_write ) += 4 ; //for the length byte;
764
797
break ;
798
+
799
+ case SYM_FLOAT :
800
+ f32 .v = (float )(IS_INTEGER (next ) ? VAL_INT64 (next ) : VAL_DECIMAL (next ));
801
+ memcpy (cp , (REBYTE * )& f32 , 4 );
802
+ cp += 4 ;
803
+ break ;
804
+ case SYM_DOUBLE :
805
+ dbl = (REBDEC )(IS_INTEGER (next ) ? VAL_INT64 (next ) : VAL_DECIMAL (next ));
806
+ memcpy (cp , (REBYTE * )& dbl , 8 );
807
+ cp += 8 ;
808
+ break ;
809
+ case SYM_FLOAT16 :
810
+ d32 = (REBDEC )(IS_INTEGER (next ) ? VAL_INT64 (next ) : VAL_DECIMAL (next ));
811
+ if (isnan (d32 )) { // 1.#NaN
812
+ ushort = 0x7e00 ;
813
+ } else {
814
+ // based on: https://stackoverflow.com/a/15118210/494472
815
+ ulong = * ((u32 * )& d32 );
816
+ u32 t1 = (ulong & 0x7fffffff ) >> 13 ; // Non-sign bits; Align mantissa on MSB
817
+ u32 t2 = (ulong & 0x80000000 ) >> 16 ; // Sign bit; Shift sign bit into position
818
+ u32 t3 = ulong & 0x7f800000 ; // Exponent
819
+
820
+ t1 -= 0x1c000 ; // Adjust bias
821
+ t1 = (t3 < 0x38800000 ) ? 0 : t1 ; // Flush-to-zero
822
+ t1 = (t3 > 0x47000000 ) ? 0x7bff : t1 ; // Clamp-to-max
823
+ // NOTE: now infinity value is also clamped to max, is it ok?
824
+
825
+ t1 |= t2 ; // Re-insert sign bit
826
+
827
+ ushort = (u16 )t1 ;
828
+ }
829
+ memcpy (cp , (REBYTE * )& ushort , 2 );
830
+ cp += 2 ;
831
+ break ;
832
+
765
833
case SYM_AT :
766
834
VAL_INDEX (buffer_write ) = VAL_INT32 (next ) - 1 ;
767
835
cp = BIN_DATA (bin ) + VAL_INDEX (buffer_write );
@@ -1352,7 +1420,6 @@ static REBCNT EncodedU32_Size(u32 value) {
1352
1420
case SYM_FLOAT16 :
1353
1421
n = 2 ;
1354
1422
ASSERT_READ_SIZE (value , cp , ep , n );
1355
- float16_s f16 ;
1356
1423
f16 .bytes .low = cp [0 ];
1357
1424
f16 .bytes .high = cp [1 ];
1358
1425
SET_DECIMAL (temp , float16to32 (f16 ) );
0 commit comments