7 #include "cln/lfloat.h"
13 #include "cl_LF_impl.h"
19 const cl_LF scale_float (const cl_LF& x, const cl_I& delta)
22 // delta=0 -> x als Ergebnis
23 // x=0.0 -> x als Ergebnis
24 // delta muß ein Integer betragsmäßig <= LF_exp_high-LF_exp_low sein.
25 // Neues LF mit um delta vergrößertem Exponenten bilden.
26 if (eq(delta,0)) { return x; } // delta=0 -> x als Ergebnis
27 var uintE uexp = TheLfloat(x)->expo;
28 if (uexp==0) { return x; }
30 // |delta| muß <= LF_exp_high-LF_exp_low < 2^32 sein. Wie bei I_to_UL:
33 var sintV sdelta = FN_to_V(delta);
35 { udelta = sdelta; goto pos; }
37 { udelta = sdelta; goto neg; }
40 var cl_heap_bignum* bn = TheBignum(delta);
41 if ((sintD)mspref(arrayMSDptr(bn->data,bn->length),0) >= 0) {
42 #define IF_LENGTH(i) \
43 if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
44 if (bn->length == i) /* genau i Digits? */ \
45 /* 2^((i-1)*intDsize-1) <= delta < 2^(i*intDsize-1) */ \
46 if ( (i*intDsize-1 > 32) \
47 && ( ((i-1)*intDsize-1 >= 32) \
48 || (mspref(arrayMSDptr(bn->data,i),0) >= (uintD)bitc(32-(i-1)*intDsize)) \
53 { udelta = get_uint1D_Dptr(arrayLSDptr(bn->data,1)); goto pos; }
55 { udelta = get_uint2D_Dptr(arrayLSDptr(bn->data,2)); goto pos; }
57 { udelta = get_uint3D_Dptr(arrayLSDptr(bn->data,3)); goto pos; }
59 { udelta = get_uint4D_Dptr(arrayLSDptr(bn->data,4)); goto pos; }
61 { udelta = get_uint4D_Dptr(arrayLSDptr(bn->data,5)); goto pos; }
63 goto overflow; // delta zu groß
65 #define IF_LENGTH(i) \
66 if (bn_minlength <= i) /* genau i Digits überhaupt möglich? */\
67 if (bn->length == i) /* genau i Digits? */ \
68 /* - 2^((i-1)*intDsize-1) > delta >= - 2^(i*intDsize-1) */\
69 if ( (i*intDsize-1 > 32) \
70 && ( ((i-1)*intDsize-1 >= 32) \
71 || (mspref(arrayMSDptr(bn->data,i),0) < (uintD)(-bitc(32-(i-1)*intDsize))) \
76 { udelta = get_sint1D_Dptr(arrayLSDptr(bn->data,1)); goto pos; }
78 { udelta = get_sint2D_Dptr(arrayLSDptr(bn->data,2)); goto pos; }
80 { udelta = get_sint3D_Dptr(arrayLSDptr(bn->data,3)); goto pos; }
82 { udelta = get_sint4D_Dptr(arrayLSDptr(bn->data,4)); goto pos; }
84 { udelta = get_sint4D_Dptr(arrayLSDptr(bn->data,5)); goto pos; }
86 goto underflow; // delta zu klein
90 pos: // udelta = delta >=0
91 if ( ((uexp = uexp+udelta) < udelta) // Exponent-Überlauf?
92 || (uexp > LF_exp_high) // oder Exponent zu groß?
95 { cl_error_floating_point_overflow(); }
98 neg: // delta <0, udelta = 2^32+delta
99 if ( ((uexp = uexp+udelta) >= udelta) // oder Exponent-Unterlauf?
100 || (uexp < LF_exp_low) // oder Exponent zu klein?
103 { cl_error_floating_point_underflow(); }
107 var uintC len = TheLfloat(x)->len;
108 return encode_LFu(TheLfloat(x)->sign,uexp,arrayMSDptr(TheLfloat(x)->data,len),len);