From 5ec5ca2758860e7249676e21153ae176fe4b01be Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 18:12:39 +0400 Subject: [PATCH] Get rid of CL_REQUIRE/CL_PROVIDE(cl_F_ln2_var). Turn cl_[SDFL]F_ln2 global variables into functions (which return a constant reference to the static value) in order to avoid static initialization order problems. --- src/float/output/cl_F_dprint.cc | 1 - src/float/transcendental/cl_F_ln2.cc | 6 ++-- src/float/transcendental/cl_F_ln2_f.cc | 6 ++-- src/float/transcendental/cl_F_ln2_var.cc | 35 +++++++++++++++++------- src/float/transcendental/cl_F_tran.h | 9 +++--- src/float/transcendental/cl_LF_ln2.cc | 12 ++++---- 6 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/float/output/cl_F_dprint.cc b/src/float/output/cl_F_dprint.cc index c34ff57..83f3db2 100644 --- a/src/float/output/cl_F_dprint.cc +++ b/src/float/output/cl_F_dprint.cc @@ -28,7 +28,6 @@ // einen String mit seiner Dezimaldarstellung. // (substring string start [end]) wie subseq, jedoch für Strings schneller. -CL_REQUIRE(cl_F_ln2_var) CL_REQUIRE(cl_F_ln10_var) #include #include "cln/output.h" diff --git a/src/float/transcendental/cl_F_ln2.cc b/src/float/transcendental/cl_F_ln2.cc index 22234a6..863a751 100644 --- a/src/float/transcendental/cl_F_ln2.cc +++ b/src/float/transcendental/cl_F_ln2.cc @@ -17,9 +17,9 @@ namespace cln { const cl_F cl_ln2 (const cl_F& y) { floattypecase(y - , return cl_SF_ln2; - , return cl_FF_ln2; - , return cl_DF_ln2; + , return cl_SF_ln2(); + , return cl_FF_ln2(); + , return cl_DF_ln2(); , return cl_ln2(TheLfloat(y)->len); ); } diff --git a/src/float/transcendental/cl_F_ln2_f.cc b/src/float/transcendental/cl_F_ln2_f.cc index 9882bb3..739acb4 100644 --- a/src/float/transcendental/cl_F_ln2_f.cc +++ b/src/float/transcendental/cl_F_ln2_f.cc @@ -16,9 +16,9 @@ namespace cln { const cl_F cl_ln2 (float_format_t f) { floatformatcase((uintC)f - , return cl_SF_ln2; - , return cl_FF_ln2; - , return cl_DF_ln2; + , return cl_SF_ln2(); + , return cl_FF_ln2(); + , return cl_DF_ln2(); , return cl_ln2(len); ); } diff --git a/src/float/transcendental/cl_F_ln2_var.cc b/src/float/transcendental/cl_F_ln2_var.cc index d9f6638..aa920d6 100644 --- a/src/float/transcendental/cl_F_ln2_var.cc +++ b/src/float/transcendental/cl_F_ln2_var.cc @@ -3,8 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_F_ln2_var) - // Specification. #include "cl_F_tran.h" @@ -18,20 +16,37 @@ CL_PROVIDE(cl_F_ln2_var) namespace cln { -// Mantisse von ln(2) : - static const uintD ln2_mantisse [64/intDsize] = - #include "cl_F_ln2_var.h" -cl_LF cl_LF_ln2 = encode_LF_array(0,0,ln2_mantisse,64/intDsize); +cl_LF& cl_LF_ln2() +{ + // Mantisse von ln(2) : + static const uintD ln2_mantisse [64/intDsize] = + #include "cl_F_ln2_var.h" + static cl_LF val = encode_LF_array(0,0,ln2_mantisse,64/intDsize); + return val; +} // Problem: If someone changes free_hook, the destructor of this // will call the new hook, passing it some pointer obtained by the old // malloc_hook. ?? -const cl_SF cl_SF_ln2 = cl_LF_to_SF(cl_LF_ln2); -const cl_FF cl_FF_ln2 = cl_LF_to_FF(cl_LF_ln2); -const cl_DF cl_DF_ln2 = cl_LF_to_DF(cl_LF_ln2); +const cl_SF& cl_SF_ln2() +{ + static const cl_SF val = cl_LF_to_SF(cl_LF_ln2()); + return val; +} + +const cl_FF& cl_FF_ln2() +{ + static const cl_FF val = cl_LF_to_FF(cl_LF_ln2()); + return val; +} + +const cl_DF& cl_DF_ln2() +{ + static const cl_DF val = cl_LF_to_DF(cl_LF_ln2()); + return val; +} } // namespace cln -CL_PROVIDE_END(cl_F_ln2_var) diff --git a/src/float/transcendental/cl_F_tran.h b/src/float/transcendental/cl_F_tran.h index 451daa6..5ad4da0 100644 --- a/src/float/transcendental/cl_F_tran.h +++ b/src/float/transcendental/cl_F_tran.h @@ -84,12 +84,11 @@ extern const cl_LF lnx_ratseries (const cl_LF& x); // requires extend by 1 extern const cl_LF cl_atanh_recip (cl_I m, uintC len); // ln(2). -extern const cl_SF cl_SF_ln2; -extern const cl_FF cl_FF_ln2; -extern const cl_DF cl_DF_ln2; -extern cl_LF cl_LF_ln2; // as long as it has ever been computed +extern const cl_SF& cl_SF_ln2(); +extern const cl_FF& cl_FF_ln2(); +extern const cl_DF& cl_DF_ln2(); +extern cl_LF& cl_LF_ln2(); // as long as it has ever been computed extern const cl_LF cl_ln2 (uintC len); // computes it even further -//CL_REQUIRE(cl_F_ln2_var) // cl_ln2(y) liefert die Zahl ln(2) im selben Float-Format wie y. // > y: ein Float diff --git a/src/float/transcendental/cl_LF_ln2.cc b/src/float/transcendental/cl_LF_ln2.cc index a07c0e1..99dd8a0 100644 --- a/src/float/transcendental/cl_LF_ln2.cc +++ b/src/float/transcendental/cl_LF_ln2.cc @@ -76,13 +76,13 @@ static inline const cl_LF compute_ln2_p2357 (uintC len) const cl_LF cl_ln2 (uintC len) { - var uintC oldlen = TheLfloat(cl_LF_ln2)->len; // vorhandene Länge + var uintC oldlen = TheLfloat(cl_LF_ln2())->len; // vorhandene Länge if (len < oldlen) - return shorten(cl_LF_ln2,len); + return shorten(cl_LF_ln2(),len); if (len == oldlen) - return cl_LF_ln2; + return cl_LF_ln2(); - // TheLfloat(cl_LF_ln2)->len um mindestens einen konstanten Faktor + // TheLfloat(cl_LF_ln2())->len um mindestens einen konstanten Faktor // > 1 wachsen lassen, damit es nicht zu häufig nachberechnet wird: var uintC newlen = len; oldlen += floor(oldlen,2); // oldlen * 3/2 @@ -90,8 +90,8 @@ const cl_LF cl_ln2 (uintC len) newlen = oldlen; // gewünschte > vorhandene Länge -> muß nachberechnen: - cl_LF_ln2 = compute_ln2(newlen); - return (len < newlen ? shorten(cl_LF_ln2,len) : cl_LF_ln2); + cl_LF_ln2() = compute_ln2(newlen); + return (len < newlen ? shorten(cl_LF_ln2(),len) : cl_LF_ln2()); } } // namespace cln