Browse Source

Fix some conversions to cl_SF, cl_FF, and cl_DF.

Some conversions failed to properly overflow/underflow with very large
exponents because of premature exponent truncation.
master
Richard Kreckel 12 years ago
parent
commit
673d1a5004
  1. 2
      src/float/conv/cl_LF_to_DF.cc
  2. 2
      src/float/conv/cl_LF_to_FF.cc
  3. 2
      src/float/conv/cl_LF_to_SF.cc
  4. 16
      src/float/dfloat/cl_DF.h
  5. 4
      src/float/dfloat/elem/cl_DF_from_I.cc
  6. 8
      src/float/ffloat/cl_FF.h
  7. 2
      src/float/ffloat/elem/cl_FF_from_I.cc
  8. 8
      src/float/sfloat/cl_SF.h
  9. 2
      src/float/sfloat/elem/cl_SF_from_I.cc

2
src/float/conv/cl_LF_to_DF.cc

@ -20,7 +20,7 @@ const cl_DF cl_LF_to_DF (const cl_LF& x)
{
// x entpacken:
var cl_signean sign;
var sintL exp;
var sintE exp;
var uintD* ptr;
var uintC len;
LF_decode(x, { return cl_DF_0; }, sign=,exp=,ptr=,len=,);

2
src/float/conv/cl_LF_to_FF.cc

@ -20,7 +20,7 @@ const cl_FF cl_LF_to_FF (const cl_LF& x)
{
// x entpacken:
var cl_signean sign;
var sintL exp;
var sintE exp;
var uintD* ptr;
var uintC len;
LF_decode(x, { return cl_FF_0; }, sign=,exp=,ptr=,len=,);

2
src/float/conv/cl_LF_to_SF.cc

@ -20,7 +20,7 @@ const cl_SF cl_LF_to_SF (const cl_LF& x)
{
// x entpacken:
var cl_signean sign;
var sintL exp;
var sintE exp;
var uintD* ptr;
var uintC len;
LF_decode(x, { return SF_0; }, sign=,exp=,ptr=,len=,);

16
src/float/dfloat/cl_DF.h

@ -153,20 +153,20 @@ inline cl_heap_dfloat* allocate_dfloat (uint32 semhi, uint32 mlo)
// encode_DF(sign,exp,mant)
// liefert ein Double-Float.
// > cl_signean sign: Vorzeichen, 0 für +, -1 für negativ.
// > sintL exp: Exponent
// > sintE exp: Exponent
// > uintQ mant: Mantisse, sollte >= 2^DF_mant_len und < 2^(DF_mant_len+1) sein.
// < cl_DF ergebnis: ein Double-Float
// Der Exponent wird auf Überlauf/Unterlauf getestet.
inline const cl_DF encode_DF (cl_signean sign, sintL exp, uintQ mant)
inline const cl_DF encode_DF (cl_signean sign, sintE exp, uintQ mant)
{
if (exp < (sintL)(DF_exp_low-DF_exp_mid))
if (exp < (sintE)(DF_exp_low-DF_exp_mid))
{ if (underflow_allowed())
{ throw floating_point_underflow_exception(); }
else
{ return cl_DF_0; }
}
else
if (exp > (sintL)(DF_exp_high-DF_exp_mid))
if (exp > (sintE)(DF_exp_high-DF_exp_mid))
{ throw floating_point_overflow_exception(); }
else
return allocate_dfloat
@ -179,21 +179,21 @@ inline const cl_DF encode_DF (cl_signean sign, sintL exp, uintQ mant)
// encode_DF(sign,exp,manthi,mantlo)
// liefert ein Double-Float.
// > cl_signean sign: Vorzeichen, 0 für +, -1 für negativ.
// > sintL exp: Exponent
// > sintE exp: Exponent
// > uintL manthi,mantlo: Mantisse 2^32*manthi+mantlo,
// sollte >= 2^DF_mant_len und < 2^(DF_mant_len+1) sein.
// < cl_DF ergebnis: ein Double-Float
// Der Exponent wird auf Überlauf/Unterlauf getestet.
inline const cl_DF encode_DF (cl_signean sign, sintL exp, uintL manthi, uintL mantlo)
inline const cl_DF encode_DF (cl_signean sign, sintE exp, uintL manthi, uintL mantlo)
{
if (exp < (sintL)(DF_exp_low-DF_exp_mid))
if (exp < (sintE)(DF_exp_low-DF_exp_mid))
{ if (underflow_allowed())
{ throw floating_point_underflow_exception(); }
else
{ return cl_DF_0; }
}
else
if (exp > (sintL)(DF_exp_high-DF_exp_mid))
if (exp > (sintE)(DF_exp_high-DF_exp_mid))
{ throw floating_point_overflow_exception(); }
else
return allocate_dfloat

4
src/float/dfloat/elem/cl_DF_from_I.cc

@ -96,7 +96,7 @@ const cl_DF cl_I_to_DF (const cl_I& x)
if (mant >= bit(DF_mant_len+1)) // rounding overflow?
{ mant = mant>>1; exp = exp+1; }
}
return encode_DF(sign,(sintL)exp,mant);
return encode_DF(sign,(sintE)exp,mant);
#else
// Die NDS besteht aus msd, msdd, msddf und len weiteren Digits.
// Das höchste in 2^64*msd+2^32*msdd+msddf gesetzte Bit ist Bit Nummer
@ -132,7 +132,7 @@ const cl_DF cl_I_to_DF (const cl_I& x)
if (manthi >= bit(DF_mant_len-32+1)) // rounding overflow?
{ manthi = manthi>>1; exp = exp+1; }
} }
return encode_DF(sign,(sintL)exp,manthi,mantlo);
return encode_DF(sign,(sintE)exp,manthi,mantlo);
#endif
}

8
src/float/ffloat/cl_FF.h

@ -136,20 +136,20 @@ inline const cl_FF make_FF (cl_sint sign, unsigned int exp, cl_uint mant)
// encode_FF(sign,exp,mant);
// liefert ein Single-Float.
// > cl_signean sign: Vorzeichen, 0 für +, -1 für negativ.
// > sintL exp: Exponent
// > sintE exp: Exponent
// > uintL mant: Mantisse, sollte >= 2^FF_mant_len und < 2^(FF_mant_len+1) sein.
// < object ergebnis: ein Single-Float
// Der Exponent wird auf Überlauf/Unterlauf getestet.
inline const cl_FF encode_FF (cl_signean sign, sintL exp, uintL mant)
inline const cl_FF encode_FF (cl_signean sign, sintE exp, uintL mant)
{
if (exp < (sintL)(FF_exp_low-FF_exp_mid))
if (exp < (sintE)(FF_exp_low-FF_exp_mid))
{ if (underflow_allowed())
{ throw floating_point_underflow_exception(); }
else
{ return cl_FF_0; }
}
else
if (exp > (sintL)(FF_exp_high-FF_exp_mid))
if (exp > (sintE)(FF_exp_high-FF_exp_mid))
{ throw floating_point_overflow_exception(); }
else
return make_FF(sign, exp+FF_exp_mid, mant & (bit(FF_mant_len)-1));

2
src/float/ffloat/elem/cl_FF_from_I.cc

@ -113,7 +113,7 @@ const cl_FF cl_I_to_FF (const cl_I& x)
{ mant = mant>>1; exp = exp+1; }
}
#endif
return encode_FF(sign,(sintL)exp,mant);
return encode_FF(sign,(sintE)exp,mant);
}
} // namespace cln

8
src/float/sfloat/cl_SF.h

@ -97,20 +97,20 @@ inline uintL SF_mant (const cl_SF& x)
// encode_SF(sign,exp,mant)
// liefert ein Short-Float.
// > cl_signean sign: Vorzeichen, 0 für +, -1 für negativ.
// > sintL exp: Exponent
// > sintE exp: Exponent
// > uintL mant: Mantisse, sollte >= 2^SF_mant_len und < 2^(SF_mant_len+1) sein.
// < object ergebnis: ein Short-Float
// Der Exponent wird auf Überlauf/Unterlauf getestet.
inline const cl_SF encode_SF (cl_signean sign, sintL exp, uintL mant)
inline const cl_SF encode_SF (cl_signean sign, sintE exp, uintL mant)
{
if (exp < (sintL)(SF_exp_low-SF_exp_mid))
if (exp < (sintE)(SF_exp_low-SF_exp_mid))
{ if (underflow_allowed())
{ throw floating_point_underflow_exception(); }
else
{ return SF_0; }
}
else
if (exp > (sintL)(SF_exp_high-SF_exp_mid))
if (exp > (sintE)(SF_exp_high-SF_exp_mid))
{ throw floating_point_overflow_exception(); }
else
return make_SF(sign, exp+SF_exp_mid, mant);

2
src/float/sfloat/elem/cl_SF_from_I.cc

@ -112,7 +112,7 @@ const cl_SF cl_I_to_SF (const cl_I& x)
{ mant = mant>>1; exp = exp+1; }
}
#endif
return encode_SF(sign,(sintL)exp,mant);
return encode_SF(sign,(sintE)exp,mant);
}
} // namespace cln
Loading…
Cancel
Save