auxposit.h /size: 8474 b    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
4
5# ifndef LMT_UTILITIES_POSIT_H
6# define LMT_UTILITIES_POSIT_H
7
8# include "libraries/softposit/source/include/softposit.h"
9# include <math.h>
10
11typedef posit32_t  posit_t;
12typedef int32_t    posit_t_s; /* get rid of compiler warning */
13typedef posit32_t *posit;
14
15/*tex
16
17    Below is the abstraction of posits for \METAPOST\ and \LUA. Currently we have only 32 bit 
18    posits, but for \TEX\ that is okay. It's why we have extra aliases for \TEX\ so that we 
19    can update \LUA\ and \METAPOST\ with 64 bit without changes. 
20
21*/
22
23# define posit_bits             32
24
25# define i64_to_posit           i64_to_p32
26# define posit_to_i64           p32_to_i64
27                                
28# define double_to_posit        convertDoubleToP32
29# define posit_to_double        convertP32ToDouble
30# define integer_to_posit       i64_to_p32
31# define posit_to_integer       p32_to_i64
32
33# define posit_round_to_integer p32_roundToInt
34
35# define posit_eq               p32_eq 
36# define posit_le               p32_le    
37# define posit_lt               p32_lt   
38# define posit_gt(a,b)          (! p32_le(a,b))
39# define posit_ge(a,b)          (! p32_lt(a,b))
40# define posit_ne(a,b)          (! p32_eq(a,b))
41                                
42# define posit_add              p32_add   
43# define posit_sub              p32_sub
44# define posit_mul              p32_mul
45# define posit_div              p32_div  
46# define posit_sqrt             p32_sqrt
47                                
48# define posit_is_NaR           isNaRP32UI
49
50# define posit_eq_zero(a) (a.v == 0)         
51# define posit_le_zero(a) (a.v <= 0)         
52# define posit_lt_zero(a) (a.v <  0)         
53# define posit_gt_zero(a) (a.v >  0)         
54# define posit_ge_zero(a) (a.v >= 0)         
55# define posit_ne_zero(a) (a.v != 0)         
56
57static inline posit_t posit_neg(posit_t a) { posit_t p ; p.v = (- (posit_t_s) a.v) & 0xFFFFFFFF; return p; } 
58static inline posit_t posit_abs(posit_t a) { posit_t p ; int mask = a.v >> 31; p.v = ((a.v + mask) ^ mask) & 0xFFFFFFFF; return p; }
59
60//     static posit_t posit_neg     (posit_t v)            { return posit_mul(v, integer_to_posit(-1)) ; }
61static inline posit_t posit_fabs    (posit_t v)            { return double_to_posit(fabs (posit_to_double(v))); }
62static inline posit_t posit_exp     (posit_t v)            { return double_to_posit(exp  (posit_to_double(v))); }
63static inline posit_t posit_log     (posit_t v)            { return double_to_posit(log  (posit_to_double(v))); }   
64static inline posit_t posit_sin     (posit_t v)            { return double_to_posit(sin  (posit_to_double(v))); }   
65static inline posit_t posit_cos     (posit_t v)            { return double_to_posit(cos  (posit_to_double(v))); }   
66static inline posit_t posit_tan     (posit_t v)            { return double_to_posit(tan  (posit_to_double(v))); }   
67static inline posit_t posit_asin    (posit_t v)            { return double_to_posit(asin (posit_to_double(v))); }   
68static inline posit_t posit_acos    (posit_t v)            { return double_to_posit(acos (posit_to_double(v))); }   
69static inline posit_t posit_atan    (posit_t v)            { return double_to_posit(atan (posit_to_double(v))); }   
70static inline posit_t posit_atan2   (posit_t v, posit_t w) { return double_to_posit(atan2(posit_to_double(v),posit_to_double(w))); }   
71static inline posit_t posit_pow     (posit_t v, posit_t w) { return double_to_posit(pow  (posit_to_double(v),posit_to_double(w))); }   
72static inline posit_t posit_round   (posit_t v)            { return posit_round_to_integer(v); }   
73static inline posit_t posit_floor   (posit_t v)            { return double_to_posit(floor(posit_to_double(v))); }   
74static inline posit_t posit_modf    (posit_t v)            { double d; return double_to_posit(modf(posit_to_double(v), &d)); }   
75   
76static inline posit_t posit_d_log   (double v)             { return double_to_posit(log  (v)); }   
77static inline posit_t posit_d_sin   (double v)             { return double_to_posit(sin  (v)); }   
78static inline posit_t posit_d_cos   (double v)             { return double_to_posit(cos  (v)); }   
79static inline posit_t posit_d_asin  (double v)             { return double_to_posit(asin (v)); }   
80static inline posit_t posit_d_acos  (double v)             { return double_to_posit(acos (v)); }   
81static inline posit_t posit_d_atan  (double v)             { return double_to_posit(atan (v)); }   
82static inline posit_t posit_d_atan2 (double v, double w)   { return double_to_posit(atan2(v,w)); }   
83                                                              
84static inline int     posit_i_round (posit_t v)            { return (int) posit_to_integer(v); }   
85   
86/*tex 
87
88    The next code is used at the \TEX\ end where we are always 32 bit, while at some 
89    point \METAPOST\ and \LUA\ will go 64 bit. 
90
91    The posit lib code is somewhat over the top wrt comparisons, so I might   
92    eventually replace that. 
93
94    Not all relevant parts are done yet (I need to check where dimensions and posits)
95    get cast. 
96
97*/
98
99typedef int       halfword;
100typedef posit32_t tex_posit;
101
102# define tex_double_to_posit(p)         double_to_posit(p)       
103# define tex_posit_to_double(p)         posit_to_double((tex_posit) { .v = (uint32_t) p })       
104
105# define tex_integer_to_posit(p)        integer_to_posit((int32_t) p)      
106# define tex_posit_to_integer(p)        posit_to_integer((tex_posit) { .v = (uint32_t) p })      
107
108# define tex_posit_round_to_integer(p)  posit_round_to_integer((tex_posit) { .v = (uint32_t) p })
109
110# define tex_posit_eq(p,q)              posit_eq((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q })             
111# define tex_posit_le(p,q)              posit_le((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q })             
112# define tex_posit_lt(p,q)              posit_lt((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q })             
113# define tex_posit_gt(p,q)              posit_gt((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q })
114# define tex_posit_ge(p,q)              posit_ge((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q })
115# define tex_posit_ne(p,q)              posit_ne((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q })
116                                
117# define tex_posit_add(p,q)             (halfword) posit_add((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q }).v
118# define tex_posit_sub(p,q)             (halfword) posit_sub((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q }).v
119# define tex_posit_mul(p,q)             (halfword) posit_mul((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q }).v
120# define tex_posit_div(p,q)             (halfword) posit_div((tex_posit) { .v = (uint32_t) p }, (tex_posit) { .v = (uint32_t) q }).v
121# define tex_posit_sqrt(p)              (halfword) posit_sqrt((tex_posit) { .v = (uint32_t) p }.v
122
123# define tex_posit_mul_by(p,q)          (halfword) posit_mul((tex_posit) { .v = (uint32_t) p }, tex_integer_to_posit(q)).v
124# define tex_posit_div_by(p,q)          (halfword) posit_div((tex_posit) { .v = (uint32_t) p }, tex_integer_to_posit(q)).v
125
126# define tex_posit_is_NaR(p)            posit_is_NaR((tex_posit) { .v = (uint32_t) p })         
127
128# define tex_posit_eq_zero(p)           posit_eq_zero((tex_posit) { .v = (uint32_t) p })
129# define tex_posit_le_zero(p)           posit_le_zero((tex_posit) { .v = (uint32_t) p })
130# define tex_posit_lt_zero(p)           posit_lt_zero((tex_posit) { .v = (uint32_t) p })
131# define tex_posit_gt_zero(p)           posit_gt_zero((tex_posit) { .v = (uint32_t) p })
132# define tex_posit_ge_zero(p)           posit_ge_zero((tex_posit) { .v = (uint32_t) p })
133# define tex_posit_ne_zero(p)           posit_ne_zero((tex_posit) { .v = (uint32_t) p })
134
135static inline halfword tex_posit_neg(halfword a) 
136{ 
137    posit32_t p ; 
138    p.v = -a & 0xFFFFFFFF; 
139    return p.v; 
140} 
141
142static inline halfword tex_posit_abs(halfword a) { 
143    posit32_t p ; 
144    int mask = a >> 31; 
145    p.v = ((a + mask) ^ mask) & 0xFFFFFFFF; 
146    return p.v; 
147}
148
149static inline tex_posit tex_dimension_to_posit(halfword p) 
150{
151    return p32_div(ui32_to_p32(p), ui32_to_p32(65536));
152}
153
154static inline halfword tex_posit_to_dimension(halfword p) 
155{
156    posit32_t x; 
157    x.v = (uint32_t) p; 
158    return (halfword) posit_to_integer(p32_mul(x, i32_to_p32(65536)));     
159}
160
161# endif
162