// scale_float(). // General includes. #include "base/cl_sysdep.h" // Specification. #include "cln/lfloat.h" // Implementation. #include "float/lfloat/cl_LF.h" #include "float/lfloat/cl_LF_impl.h" #include "float/cl_F.h" #include "integer/cl_I.h" namespace cln { const cl_LF scale_float (const cl_LF& x, const cl_I& delta) { // Methode: // delta=0 -> x als Ergebnis // x=0.0 -> x als Ergebnis // delta muß ein Integer betragsmäßig <= LF_exp_high-LF_exp_low sein. // Neues LF mit um delta vergrößertem Exponenten bilden. if (eq(delta,0)) { return x; } // delta=0 -> x als Ergebnis var uintE uexp = TheLfloat(x)->expo; if (uexp==0) { return x; } var uintE udelta; // |delta| muß <= LF_exp_high-LF_exp_low < 2^intEsize sein. if (fixnump(delta)) { // Fixnum var sintV sdelta = FN_to_V(delta); if (sdelta >= 0) { udelta = sdelta; goto pos; } else { udelta = sdelta; goto neg; } } else { // Bignum var cl_heap_bignum* bn = TheBignum(delta); if ((sintD)mspref(arrayMSDptr(bn->data,bn->length),0) >= 0) { // delta >= 0 try { udelta = cl_I_to_UE(delta); goto pos; } catch (const runtime_exception&) { goto overflow; } } else { // delta < 0 try { udelta = cl_I_to_E(delta); goto neg; } catch (const runtime_exception&) { goto underflow; } } } pos: // udelta = delta >=0 if ( ((uexp = uexp+udelta) < udelta) // Exponent-Überlauf? || (uexp > LF_exp_high) // oder Exponent zu groß? ) overflow: { throw floating_point_overflow_exception(); } goto ok; neg: // delta <0, udelta = 2^intEsize+delta if ( ((uexp = uexp+udelta) >= udelta) // oder Exponent-Unterlauf? || (uexp < LF_exp_low) // oder Exponent zu klein? ) underflow: { throw floating_point_underflow_exception(); } goto ok; ok: var uintC len = TheLfloat(x)->len; return encode_LFu(TheLfloat(x)->sign,uexp,arrayMSDptr(TheLfloat(x)->data,len),len); } } // namespace cln