diff --git a/ttmath/ttmath.h b/ttmath/ttmath.h index b687138..cd5f835 100644 --- a/ttmath/ttmath.h +++ b/ttmath/ttmath.h @@ -97,10 +97,13 @@ namespace ttmath -2.7 = -3 */ template - ValueType Round(const ValueType & x) + ValueType Round(const ValueType & x, ErrorCode * err = 0) { ValueType result( x ); - result.Round(); + uint c = result.Round(); + + if( err ) + *err = c ? err_overflow : err_ok; return result; } @@ -298,7 +301,7 @@ namespace ttmath (you don't have to call this function) */ template - void PrepareSin(ValueType & x, bool & change_sign) + uint PrepareSin(ValueType & x, bool & change_sign) { ValueType temp; @@ -314,12 +317,10 @@ namespace ttmath // we're reducing the period 2*PI // (for big values there'll always be zero) temp.Set2Pi(); - if( x > temp ) - { - x.Div( temp ); - x.RemainFraction(); - x.Mul( temp ); - } + + if( x.Mod(temp) ) + return 1; + // we're setting 'x' as being in the range of <0, 0.5PI> @@ -340,6 +341,8 @@ namespace ttmath x.Sub( temp ); x = temp - x; } + + return 0; } @@ -426,7 +429,7 @@ namespace ttmath if( c ) // Sin is from <-1,1> and cannot make an overflow // but the carry can be from the Taylor series - // (then we only breaks our calculations) + // (then we only break our calculations) break; if( addition ) @@ -458,15 +461,15 @@ namespace ttmath this function calculates the Sine */ template - ValueType Sin(ValueType x) + ValueType Sin(ValueType x, ErrorCode * err = 0) { using namespace auxiliaryfunctions; - ValueType one; + ValueType one, result; bool change_sign; - PrepareSin( x, change_sign ); - ValueType result = Sin0pi05( x ); + if( err ) + *err = err_ok; if( PrepareSin( x, change_sign ) ) { @@ -506,22 +509,24 @@ namespace ttmath we're using the formula cos(x) = sin(x + PI/2) */ template - ValueType Cos(ValueType x) + ValueType Cos(ValueType x, ErrorCode * err = 0) { ValueType pi05; pi05.Set05Pi(); - x.Add( pi05 ); + uint c = x.Add( pi05 ); if( c ) { if( err ) *err = err_overflow; - } return ValueType(); // result is undefined (NaN is set by default) } + return Sin(x, err); + } + /*! this function calulates the Tangent @@ -536,7 +541,10 @@ namespace ttmath template ValueType Tan(const ValueType & x, ErrorCode * err = 0) { - ValueType result = Cos(x); + ValueType result = Cos(x, err); + + if( err && *err != err_ok ) + return result; if( result.IsZero() ) { @@ -548,10 +556,7 @@ namespace ttmath return result; } - if( err ) - *err = err_ok; - - return Sin(x) / result; + return Sin(x, err) / result; } @@ -578,7 +583,10 @@ namespace ttmath template ValueType Cot(const ValueType & x, ErrorCode * err = 0) { - ValueType result = Sin(x); + ValueType result = Sin(x, err); + + if( err && *err != err_ok ) + return result; if( result.IsZero() ) { @@ -590,10 +598,7 @@ namespace ttmath return result; } - if( err ) - *err = err_ok; - - return Cos(x) / result; + return Cos(x, err) / result; } @@ -2053,14 +2058,17 @@ namespace ttmath e.g. mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6 - mod(-12.6 ; 3) = -0.6 + mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6) mod( 12.6 ; -3) = 0.6 mod(-12.6 ; -3) = -0.6 */ template - ValueType Mod(ValueType a, const ValueType & b) - { - a.Mod(b); + ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0) + { + uint c = a.Mod(b); + + if( err ) + *err = c ? err_overflow : err_ok; return a; } diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index 2c1e4b8..4f96251 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -2693,7 +2693,7 @@ public: tchar_t decimal_point = TTMATH_COMMA_CHARACTER_1 ) const { static tchar_t error_overflow_msg[] = TTMATH_TEXT("overflow"); - static char error_nan_msg[] = "NaN"; + static tchar_t error_nan_msg[] = TTMATH_TEXT("NaN"); result.erase(); if( IsNan() ) diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index bf3845e..fefbdc4 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -976,7 +976,7 @@ public: // table[i] = result.table[i]; // testing carry - for( ; i with methods without any assembler code this file is included at the end of ttmathuint.h */ +#pragma message("TTMATH_NOASM") + namespace ttmath { @@ -95,7 +96,7 @@ namespace ttmath for(i=0 ; i uint UInt::AddInt(uint value, uint index) { - register uint b = value_size; - register uint * p1 = table; + uint b = value_size; + uint * p1 = table; + uint c; TTMATH_ASSERT( index < value_size ) #ifndef __GNUC__ - __asm { mov ecx, [b] @@ -204,14 +201,12 @@ namespace ttmath end: setc al movzx eax, al + mov [c], eax } - #endif #ifdef __GNUC__ - register uint c; - __asm__ __volatile__( "push %%eax \n" @@ -238,11 +233,11 @@ namespace ttmath : "=d" (c) : "a" (value), "c" (b), "0" (index), "b" (p1) : "cc", "memory" ); - - return c; #endif - TTMATH_LOG("UInt32::AddInt") + TTMATH_LOG("UInt::AddInt") + + return c; } @@ -281,8 +276,9 @@ namespace ttmath template uint UInt::AddTwoInts(uint x2, uint x1, uint index) { - register uint b = value_size; - register uint * p1 = table; + uint b = value_size; + uint * p1 = table; + uint c; TTMATH_ASSERT( index < value_size - 1 ) @@ -313,13 +309,11 @@ namespace ttmath end: setc al movzx eax, al + mov [c], eax } #endif - #ifdef __GNUC__ - register uint c; - __asm__ __volatile__( "push %%ecx \n" @@ -350,11 +344,11 @@ namespace ttmath : "=a" (c) : "c" (b), "d" (index), "b" (p1), "S" (x1), "0" (x2) : "cc", "memory" ); - - return c; #endif - TTMATH_LOG("UInt32::AddTwoInts") + TTMATH_LOG("UInt::AddTwoInts") + + return c; } @@ -380,7 +374,6 @@ namespace ttmath // this algorithm doesn't require it #ifndef __GNUC__ - __asm { mov ecx,[b] @@ -404,6 +397,7 @@ namespace ttmath setc al movzx eax, al + mov [c], eax } #endif @@ -435,10 +429,11 @@ namespace ttmath : "D" (c), "c" (b), "b" (p1), "S" (p2) : "%eax", "cc", "memory" ); - return c; #endif - TTMATH_LOG("UInt32::Sub") + TTMATH_LOG("UInt::Sub") + + return c; } @@ -466,8 +461,9 @@ namespace ttmath template uint UInt::SubInt(uint value, uint index) { - register uint b = value_size; - register uint * p1 = table; + uint b = value_size; + uint * p1 = table; + uint c; TTMATH_ASSERT( index < value_size ) @@ -495,13 +491,12 @@ namespace ttmath end: setc al movzx eax, al + mov [c], eax } #endif #ifdef __GNUC__ - register uint c; - __asm__ __volatile__( "push %%eax \n" @@ -528,12 +523,11 @@ namespace ttmath : "=d" (c) : "a" (value), "c" (b), "0" (index), "b" (p1) : "cc", "memory" ); - - return c; #endif - TTMATH_LOG("UInt32::SubInt") + TTMATH_LOG("UInt::SubInt") + return c; } @@ -577,6 +571,7 @@ namespace ttmath setc al movzx eax, al + mov [c], eax } #endif @@ -606,12 +601,11 @@ namespace ttmath : "=a" (c) : "0" (c), "c" (b), "b" (p1) : "cc", "memory" ); - - return c; #endif - TTMATH_LOG("UInt32::Rcl2_one") + TTMATH_LOG("UInt::Rcl2_one") + return c; } @@ -652,6 +646,7 @@ namespace ttmath setc al movzx eax, al + mov [c], eax } #endif @@ -677,11 +672,11 @@ namespace ttmath : "=a" (c) : "0" (c), "c" (b), "b" (p1) : "cc", "memory" ); - - return c; #endif - TTMATH_LOG("UInt32::Rcr2_one") + TTMATH_LOG("UInt::Rcr2_one") + + return c; } @@ -743,6 +738,7 @@ namespace ttmath jnz p and eax, 1 + mov dword ptr [c], eax } #endif @@ -790,11 +786,11 @@ namespace ttmath : "=a" (c) : "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask) : "cc", "memory" ); - - return c; #endif - TTMATH_LOG("UInt32::Rcl2") + TTMATH_LOG("UInt::Rcl2") + + return c; } @@ -860,6 +856,8 @@ namespace ttmath rol eax, 1 // bit 31 will be bit 0 and eax, 1 + + mov dword ptr [c], eax } #endif @@ -910,11 +908,11 @@ namespace ttmath : "=a" (c) : "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask) : "cc", "memory" ); - - return c; #endif - TTMATH_LOG("UInt32::Rcr2") + TTMATH_LOG("UInt::Rcr2") + + return c; } @@ -926,6 +924,7 @@ namespace ttmath template sint UInt::FindLeadingBitInWord(uint x) { + sint result; #ifndef __GNUC__ __asm @@ -933,13 +932,13 @@ namespace ttmath mov edx,-1 bsr eax,[x] cmovz eax,edx + + mov [result], eax } #endif #ifdef __GNUC__ - register sint result; - __asm__ __volatile__( "bsrl %1, %0 \n" @@ -951,9 +950,9 @@ namespace ttmath : "R" (x) : "cc" ); - return result; - #endif + + return result; } @@ -976,6 +975,7 @@ namespace ttmath TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT ) uint v = value; + uint old_bit; #ifndef __GNUC__ __asm @@ -987,13 +987,12 @@ namespace ttmath setc bl movzx ebx, bl - mov eax, ebx + mov [old_bit], ebx } #endif #ifdef __GNUC__ - uint old_bit; __asm__ __volatile__( @@ -1005,11 +1004,10 @@ namespace ttmath : "=a" (v), "=b" (old_bit) : "0" (v), "1" (bit) : "cc" ); - - return old_bit; #endif value = v; + return old_bit; } @@ -1101,7 +1099,7 @@ namespace ttmath these variables have similar meaning like those in the multiplication algorithm MulTwoWords */ - + TTMATH_ASSERT( c != 0 ) #ifndef __GNUC__