This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit c6461c6d88bfd5b55f07751355dfcd486719744e Author: Pedro F. Giffuni <[email protected]> AuthorDate: Tue Aug 25 23:41:55 2026 -0500 Calc: use STD C++ for Complex functions. At first many of these calculations were handwritten and could overflow. Later we started using the available Boost for some edge cases which was a good solution to make up for the lack of such function in some of the supported platforms. The latest versions of Boost though, are deprecating Boost complex functions in favor of the C++ standard library and its now time to catch up. As a result of this change, the results of IMSECH and IMCSCH don't match the examples in the the help but matches the results in Excel. --- main/scaddins/source/analysis/analysishelper.cxx | 211 ++++------------------- 1 file changed, 31 insertions(+), 180 deletions(-) diff --git a/main/scaddins/source/analysis/analysishelper.cxx b/main/scaddins/source/analysis/analysishelper.cxx index 5b56a270b4..e6b1b153ce 100644 --- a/main/scaddins/source/analysis/analysishelper.cxx +++ b/main/scaddins/source/analysis/analysishelper.cxx @@ -1943,10 +1943,7 @@ double Complex::Arg( void ) const THROWDEF_RTE_IAE if( Num.real() == 0.0 && Num.imag() == 0.0 ) THROW_IAE; - double phi = acos( Num.real() / Abs() ); - - if( Num.imag() < 0.0 ) - phi = -phi; + double phi = std::atan2(Num.imag(), Num.real()); return phi; } @@ -1965,68 +1962,34 @@ void Complex::Power( double fPower ) THROWDEF_RTE_IAE THROW_IAE; } - double p, phi; - - p = Abs(); - - phi = acos( Num.real() / p ); - if( Num.imag() < 0.0 ) - phi = -phi; - - p = pow( p, fPower ); - phi *= fPower; - - Num = double_complex (cos( phi ) * p, sin( phi ) * p); + Num = std::pow(Num , fPower); } void Complex::Sqrt( void ) { - static const double fMultConst = 0.7071067811865475; // ...2440084436210485 = 1/sqrt(2) - double p = Abs(); - double i_ = sqrt( p - Num.real() ) * fMultConst; - Num = double_complex (sqrt( p + Num.real() ) * fMultConst, ( Num.imag() < 0.0 )? -i_ : i_); + Num = std::sqrt(Num); } void Complex::Sin( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - - r_ = sin( r ) * cosh( i ); - i = cos( r ) * sinh( i ); - r = r_; - } - else - r = sin( r ); - Num = double_complex ( r, i ); + Num = std::sin( Num ); } void Complex::Cos( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - - r_ = cos( r ) * cosh( i ); - i = -( sin( r ) * sinh( i ) ); - r = r_; - } - else - r = cos( r ); - Num = double_complex ( r, i ); + Num = std::cos ( Num ); } @@ -2035,23 +1998,15 @@ void Complex::Div( const Complex& z ) THROWDEF_RTE_IAE if( z.Num.real() == 0 && z.Num.imag() == 0 ) THROW_IAE; - double a1 = Num.real(); - double a2 = z.Num.real(); - double b1 = Num.imag(); - double b2 = z.Num.imag(); - - double f = 1.0 / ( a2 * a2 + b2 * b2 ); - - Num = f * double_complex ( a1 * a2 + b1 * b2 , a2 * b1 - a1 * b2 ); + Num /= z.Num; - if( !c ) c = z.c; } void Complex::Exp( void ) { - double fE = exp( Num.real() ); - Num = fE * double_complex ( cos( Num.imag() ), sin( Num.imag() ) ); + + Num = std::exp( Num ); } @@ -2061,16 +2016,7 @@ void Complex::Ln( void ) THROWDEF_RTE_IAE if( r == 0.0 && i == 0.0 ) THROW_IAE; - double fAbs = Abs(); - sal_Bool bNegi = i < 0.0; - - i = acos( r / fAbs ); - - if( bNegi ) - i = -i; - - r = log( fAbs ); - Num = double_complex ( r, i ); + Num = std::log ( Num ); } @@ -2095,168 +2041,73 @@ void Complex::Tan(void) THROWDEF_RTE_IAE { if( !::rtl::math::isValidArcArg( 2.0 * r ) ) THROW_IAE; - double fScale =1.0 / ( cos( 2.0 * r ) + cosh( 2.0 * i )); - r = sin( 2.0 * r ) * fScale; - i = sinh( 2.0 * i ) * fScale; } else { if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - r = tan( r ); } - Num = double_complex ( r, i ); + Num = std::tan ( Num ); } void Complex::Sec( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if( i ) - { - if( !::rtl::math::isValidArcArg( 2 * r ) ) - THROW_IAE; - double fScale = 1.0 / (cosh( 2.0 * i) + cos ( 2.0 * r)); - double r_; - r_ = 2.0 * cos( r ) * cosh( i ) * fScale; - i = 2.0 * sin( r ) * sinh( i ) * fScale; - r = r_; - } - else - { - if( !::rtl::math::isValidArcArg( r ) ) - THROW_IAE; - r = 1.0 / cos( r ); - } - Num = double_complex ( r, i ); + + Cos(); + Num = 1.0 / Num; } void Complex::Csc( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if( i ) - { - if( !::rtl::math::isValidArcArg( 2 * r ) ) - THROW_IAE; - double fScale = 1.0 / (cosh( 2.0 * i) - cos ( 2.0 * r)); - double r_; - r_ = 2.0 * sin( r ) * cosh( i ) * fScale; - i = -2.0 * cos( r ) * sinh( i ) * fScale; - r = r_; - } - else - { - if( !::rtl::math::isValidArcArg( r ) ) - THROW_IAE; - r = 1.0 / sin( r ); - } - Num = double_complex ( r, i ); + + Sin(); + Num = 1.0 / Num; } void Complex::Cot(void) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if ( i ) - { - if( !::rtl::math::isValidArcArg( 2.0 * r ) ) - THROW_IAE; - double fScale =1.0 / ( cosh( 2.0 * i ) - cos( 2.0 * r ) ); - r = sin( 2.0 * r ) * fScale; - i = - ( sinh( 2.0 * i ) * fScale ); - } - else - { - if( !::rtl::math::isValidArcArg( r ) ) - THROW_IAE; - r = 1.0 / tan( r ); - } - Num = double_complex ( r, i ); + + Tan(); + Num = 1.0 / Num; } void Complex::Sinh( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - r_ = sinh( r ) * cos( i ); - i = cosh( r ) * sin( i ); - r = r_; - } - else - r = sinh( r ); - Num = double_complex ( r, i ); + Num = std::sinh( Num ); } void Complex::Cosh( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - r_ = cosh( r ) * cos( i ); - i = sinh( r ) * sin( i ); - r = r_; - } - else - r = cosh( r ); - Num = double_complex ( r, i ); + Num = std::cosh( Num ); } void Complex::Sech(void) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if ( i ) - { - if( !::rtl::math::isValidArcArg( 2.0 * r ) ) - THROW_IAE; - double fScale =1.0 / ( cosh( 2.0 * r ) + cos( 2.0 * i )); - double r_; - r_ = 2.0 * cosh( r ) * cos( i ) * fScale; - i = - (2.0 * sinh( r ) * sin( i ) * fScale ); - r = r_ ; - } - else - { - if( !::rtl::math::isValidArcArg( r ) ) - THROW_IAE; - r = 1.0 / cosh( r ); - } - Num = double_complex ( r, i ); + + Cosh(); + Num = 1.0 / Num; } void Complex::Csch(void) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if ( i ) - { - if( !::rtl::math::isValidArcArg( 2.0 * r ) ) - THROW_IAE; - double fScale =1.0 / ( cosh( 2.0 * r ) - cos( 2.0 * i )); - double r_; - r_ = 2.0 * sinh( r ) * cos( i ) * fScale; - i = - ( 2.0 * cosh( r ) * sin( i ) * fScale ); - r = r_ ; - } - else - { - if( !::rtl::math::isValidArcArg( r ) ) - THROW_IAE; - r = 1.0 / sinh( r ); - } - Num = double_complex ( r, i ); + + Sinh(); + Num = 1.0 / Num; }
