PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/cln-1.3.2/src/float/sfloat/algebraic/cl_SF_sqrt.cc

#
C++ | 68 lines | 32 code | 8 blank | 28 comment | 6 complexity | 7d4c4ff9582acd3d4859f903676ac759 MD5 | raw file
Possible License(s): GPL-2.0
  1. // sqrt().
  2. // General includes.
  3. #include "base/cl_sysdep.h"
  4. // Specification.
  5. #include "cln/sfloat.h"
  6. // Implementation.
  7. #include "float/sfloat/cl_SF.h"
  8. #include "base/cl_low.h"
  9. namespace cln {
  10. const cl_SF sqrt (const cl_SF& x)
  11. {
  12. // Methode:
  13. // x = 0.0 -> Ergebnis 0.0
  14. // Ergebnis-Vorzeichen := positiv,
  15. // Ergebnis-Exponent := ceiling(e/2),
  16. // Ergebnis-Mantisse:
  17. // Bilde aus [1,m15,...,m0,(19 Nullbits)] bei geradem e,
  18. // aus [0,1,m15,...,m0,(18 Nullbits)] bei ungeradem e
  19. // die Ganzzahl-Wurzel, eine 18-Bit-Zahl mit einer führenden 1.
  20. // Runde das letzte Bit weg:
  21. // Bit 0 = 0 -> abrunden,
  22. // Bit 0 = 1 und Wurzel exakt -> round-to-even,
  23. // Bit 0 = 1 und Rest >0 -> aufrunden.
  24. // Dabei um ein Bit nach rechts schieben.
  25. // Bei Aufrundung auf 2^17 (rounding overflow) Mantisse um 1 Bit nach rechts
  26. // schieben und Exponent incrementieren.
  27. // x entpacken:
  28. var sintL exp;
  29. var uint32 mant;
  30. SF_decode(x, { return x; }, ,exp=,mant=);
  31. // Um die 64-Bit-Ganzzahl-Wurzel ausnutzen zu können, fügen wir beim
  32. // Radikanden 46 bzw. 47 statt 18 bzw. 19 Nullbits an.
  33. if (exp & bit(0))
  34. // e ungerade
  35. { mant = mant << (31-(SF_mant_len+1)); exp = exp+1; }
  36. else
  37. // e gerade
  38. { mant = mant << (32-(SF_mant_len+1)); }
  39. exp = exp >> 1; // exp := exp/2
  40. var bool exactp;
  41. isqrt_64_32(mant,0, mant=,exactp=); // mant := isqrt(mant*2^32), eine 32-Bit-Zahl
  42. // Die hinteren 31-SF_mant_len Bits wegrunden:
  43. if ( ((mant & bit(30-SF_mant_len)) ==0) // Bit 14 =0 -> abrunden
  44. || ( ((mant & (bit(30-SF_mant_len)-1)) ==0) // Bit 14 =1 und Bits 13..0 >0 -> aufrunden
  45. && exactp // Bit 14 =1 und Bits 13..0 =0, aber Rest -> aufrunden
  46. // round-to-even, je nach Bit 15 :
  47. && ((mant & bit(31-SF_mant_len)) ==0)
  48. ) )
  49. // abrunden
  50. { mant = mant >> (31-SF_mant_len); }
  51. else
  52. // aufrunden
  53. { mant = mant >> (31-SF_mant_len);
  54. mant += 1;
  55. if (mant >= bit(SF_mant_len+1)) // rounding overflow?
  56. { mant = mant>>1; exp = exp+1; }
  57. }
  58. return encode_SF(0,exp,mant);
  59. }
  60. } // namespace cln