9 // The immediate word contains:
10 // |..|.......|..........................|....|
11 // sign exponent mantissa tag
13 #define SF_value_shift 7 // could also be = cl_value_shift
14 #define SF_exp_len 8 // number of bits in the exponent
15 #define SF_mant_len 16 // number of bits in the mantissa
16 // (excluding the hidden bit)
17 #define SF_mant_hiddenbit 1 // yes, we have a hidden bit representation
18 // (this is hardwired in some of the code)
19 #define SF_exp_low 1 // minimum exponent
20 #define SF_exp_mid bit(SF_exp_len-1) // exponent bias
21 #define SF_exp_high (bit(SF_exp_len)-1) // maximum exponent
22 #define SF_exp_shift (SF_mant_len+SF_mant_shift) // lowest exponent bit
23 #define SF_mant_shift SF_value_shift // lowest mantissa bit
24 #define SF_sign_shift (cl_pointer_size - 1)
26 // Builds a float from the immediate word.
27 inline cl_SF::cl_SF (struct cl_sfloat * null, cl_uint w)
28 : cl_F ((cl_private_thing) w) { unused null; }
29 inline const cl_SF cl_SF_from_word (cl_uint word)
31 return cl_SF((struct cl_sfloat *) 0, word);
34 // Builds a float word from sign (0 or -1), exponent and mantissa.
35 inline cl_uint make_SF_word (cl_sint sign, unsigned int exp, cl_uint mant)
37 return (sign & ((cl_uint)1 << SF_sign_shift))
38 | (exp << SF_exp_shift)
40 | ((mant & (bit(SF_mant_len)-1)) << SF_mant_shift)
42 | (mant << SF_mant_shift)
44 | (cl_SF_tag << cl_tag_shift);
47 // Builds a float from sign (0 or -1), exponent and mantissa.
48 inline const cl_SF make_SF (cl_sint sign, unsigned int exp, cl_uint mant)
50 return cl_SF_from_word(make_SF_word(sign,exp,mant));
54 #define SF_0 make_SF(0,0,0)
56 #define SF_1 make_SF(0,SF_exp_mid+1,bit(SF_mant_len))
58 #define SF_minus1 make_SF(-1,SF_exp_mid+1,bit(SF_mant_len))
61 // Entpacken eines Short-Float:
62 // SF_decode(obj, zero_statement, sign=,exp=,mant=);
63 // zerlegt ein Short-Float obj.
64 // Ist obj=0.0, wird zero_statement ausgeführt.
65 // Sonst: cl_signean sign = Vorzeichen (0 = +, -1 = -),
66 // sintL exp = Exponent (vorzeichenbehaftet),
67 // uintL mant = Mantisse (>= 2^SF_mant_len, < 2^(SF_mant_len+1))
68 inline uintL SF_uexp (const cl_SF& x)
70 return (x.word >> SF_exp_shift) & (bit(SF_exp_len)-1);
72 inline cl_signean SF_sign (const cl_SF& x)
74 return ((cl_sint)x.word << (cl_pointer_size-1 - SF_sign_shift)) >> (cl_pointer_size-1);
76 inline uintL SF_mant (const cl_SF& x)
82 ((uintL)(x.word >> SF_mant_shift) & (bit(SF_mant_len)-1));
84 #define SF_decode(_x, zero_statement, sign_zuweisung,exp_zuweisung,mant_zuweisung) \
85 { var uintL uexp = SF_uexp(_x); \
87 { zero_statement } /* e=0 -> Zahl 0.0 */ \
89 { exp_zuweisung (sintL)(uexp - SF_exp_mid); /* Exponent */ \
90 unused (sign_zuweisung SF_sign(_x)); /* Vorzeichen */\
91 mant_zuweisung SF_mant(_x); /* Mantisse */ \
94 // Einpacken eines Short-Float:
95 // encode_SF(sign,exp,mant)
96 // liefert ein Short-Float.
97 // > cl_signean sign: Vorzeichen, 0 für +, -1 für negativ.
98 // > sintL exp: Exponent
99 // > uintL mant: Mantisse, sollte >= 2^SF_mant_len und < 2^(SF_mant_len+1) sein.
100 // < object ergebnis: ein Short-Float
101 // Der Exponent wird auf Überlauf/Unterlauf getestet.
102 inline const cl_SF encode_SF (cl_signean sign, sintL exp, uintL mant)
104 if (exp < (sintL)(SF_exp_low-SF_exp_mid))
105 { if (underflow_allowed())
106 { cl_error_floating_point_underflow(); }
111 if (exp > (sintL)(SF_exp_high-SF_exp_mid))
112 { cl_error_floating_point_overflow(); }
114 return make_SF(sign, exp+SF_exp_mid, mant);
118 // Liefert zu einem Short-Float x : (futruncate x), ein SF.
119 // x wird von der 0 weg zur nächsten ganzen Zahl gerundet.
120 extern const cl_SF futruncate (const cl_SF& x);
122 // SF_to_I(x) wandelt ein Short-Float x, das eine ganze Zahl darstellt,
123 // in ein Integer um.
124 extern const cl_I cl_SF_to_I (const cl_SF& x);
126 // cl_I_to_SF(x) wandelt ein Integer x in ein Short-Float um und rundet dabei.
127 extern const cl_SF cl_I_to_SF (const cl_I& x);
129 // cl_RA_to_SF(x) wandelt eine rationale Zahl x in ein Short-Float um
131 extern const cl_SF cl_RA_to_SF (const cl_RA& x);
133 #endif /* _CL_SF_H */