added: using NaN flag in method Big::ToDouble() and Big::FromDouble()
changed: some cosmetic changes to get rid of warnings generated by MS Visual 2008 when warning level is 4 changed: names of labels in asm code: p to ttmath_loop, end to ttmath_end p2 to ttmath_loop2 Robert Muir reported that there was a confict with boost::end git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@156 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
bb2583649e
commit
d789ac5396
29
CHANGELOG
29
CHANGELOG
|
@ -1,4 +1,4 @@
|
|||
Version 0.8.5 prerelease (2009.05.15):
|
||||
Version 0.8.5 prerelease (2009.06.11):
|
||||
* fixed: Big::Mod(x) didn't correctly return a carry
|
||||
and the result was sometimes very big (even greater than x)
|
||||
* fixed: global function Mod(x) didn't set an ErrorCode object
|
||||
|
@ -7,7 +7,7 @@ Version 0.8.5 prerelease (2009.05.15):
|
|||
* changed: function Sin(x) to Sin(x, ErrorCode * err=0)
|
||||
when x was very big the function returns zero
|
||||
now it sets ErrorCode object to err_overflow
|
||||
and the result is undefined
|
||||
and the result has a NaN flag set
|
||||
the same is to Cos() function
|
||||
* changed: PrepareSin(x) is using Big::Mod() now when reducing 2PI period
|
||||
should be a little accurate especially on a very big 'x'
|
||||
|
@ -29,6 +29,31 @@ Version 0.8.5 prerelease (2009.05.15):
|
|||
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
||||
three forms: asm x86, asm x86_64, no-asm
|
||||
those methods are used by the Karatsuba multiplication algorithm
|
||||
* added: to Big<> class: support for NaN flag (Not a Number)
|
||||
bool Big::IsNan() - returns true if the NaN flag is set
|
||||
void Big::SetNan() - sets the NaN flag
|
||||
The NaN flag is set by default after creating an object:
|
||||
Big<1, 2> a; // NaN is set (it means the object has not a valid number)
|
||||
std::cout << a; // cout gives "NaN"
|
||||
a = 123; // now NaN is not set
|
||||
std::cout << a; // cout gives "123"
|
||||
The NaN is set if there was a carry during calculations
|
||||
a.Mul(very_big_value); // a will have a NaN set
|
||||
The NaN is set if an argument is NaN too
|
||||
b.SetNan();
|
||||
a.Add(b); // a will have NaN because b has NaN too
|
||||
If you try to do something on a NaN object, the result is a NaN too
|
||||
a.SetNan();
|
||||
a.Add(2); // a is still a NaN
|
||||
The NaN is set if you use incorrect arguments
|
||||
a.Ln(-10); // a will have the NaN flag
|
||||
The only way to clear the NaN flag is to assign a correct value or other correct object,
|
||||
supposing 'a' has NaN flag, to remove the flag you can either:
|
||||
a = 10;
|
||||
a.FromInt(30);
|
||||
a.SetOne();
|
||||
a.FromBig(other_object_without_nan);
|
||||
etc.
|
||||
|
||||
|
||||
Version 0.8.4 (2009.05.08):
|
||||
|
|
|
@ -45,6 +45,12 @@
|
|||
\brief Mathematics functions.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//warning C4127: conditional expression is constant
|
||||
#pragma warning( disable: 4127 )
|
||||
#endif
|
||||
|
||||
|
||||
#include "ttmathbig.h"
|
||||
#include "ttmathobjects.h"
|
||||
|
||||
|
@ -1727,7 +1733,7 @@ namespace ttmath
|
|||
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckIndexOne(ValueType & x, const ValueType & index, ErrorCode * err)
|
||||
bool RootCheckIndexOne(const ValueType & index, ErrorCode * err)
|
||||
{
|
||||
ValueType one;
|
||||
one.SetOne();
|
||||
|
@ -1769,11 +1775,12 @@ namespace ttmath
|
|||
|
||||
|
||||
template<class ValueType>
|
||||
bool RootCheckXZero(ValueType & x, const ValueType & index, ErrorCode * err)
|
||||
bool RootCheckXZero(ValueType & x, ErrorCode * err)
|
||||
{
|
||||
if( x.IsZero() )
|
||||
{
|
||||
// root(0;index) is zero (if index!=0)
|
||||
// RootCheckIndexZero() must be called beforehand
|
||||
x.SetZero();
|
||||
|
||||
if( err )
|
||||
|
@ -1842,9 +1849,9 @@ namespace ttmath
|
|||
|
||||
if( RootCheckIndexSign(x, index, err) ) return x;
|
||||
if( RootCheckIndexZero(x, index, err) ) return x;
|
||||
if( RootCheckIndexOne (x, index, err) ) return x;
|
||||
if( RootCheckIndexOne ( index, err) ) return x;
|
||||
if( RootCheckIndexFrac(x, index, err) ) return x;
|
||||
if( RootCheckXZero (x, index, err) ) return x;
|
||||
if( RootCheckXZero (x, err) ) return x;
|
||||
|
||||
// index integer and index!=0
|
||||
// x!=0
|
||||
|
@ -2079,4 +2086,9 @@ namespace ttmath
|
|||
*/
|
||||
#include "ttmathparser.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( default: 4127 )
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -704,7 +704,12 @@ public:
|
|||
// there shouldn't be a carry here because
|
||||
// (1) (2) guarantee that the mantissa of this
|
||||
// is greater than or equal to the mantissa of the ss2
|
||||
uint c_temp = mantissa.Sub(ss2.mantissa);
|
||||
|
||||
#ifdef TTMATH_DEBUG
|
||||
// this is to get rid of a warning saying that c_temp is not used
|
||||
uint c_temp = /* mantissa.Sub(ss2.mantissa); */
|
||||
#endif
|
||||
mantissa.Sub(ss2.mantissa);
|
||||
|
||||
TTMATH_ASSERT( c_temp == 0 )
|
||||
}
|
||||
|
@ -2022,9 +2027,10 @@ public:
|
|||
// If E=2047 and F is zero and S is 1, then V=-Infinity
|
||||
// If E=2047 and F is zero and S is 0, then V=Infinity
|
||||
|
||||
// at the moment we do not support NaN, -Infinity and +Infinity
|
||||
// we do not support -Infinity and +Infinity
|
||||
// we assume that there is always NaN
|
||||
|
||||
SetZero();
|
||||
SetNaN();
|
||||
}
|
||||
else
|
||||
if( e > 0 )
|
||||
|
@ -2135,9 +2141,10 @@ public:
|
|||
// If E=2047 and F is zero and S is 1, then V=-Infinity
|
||||
// If E=2047 and F is zero and S is 0, then V=Infinity
|
||||
|
||||
// at the moment we do not support NaN, -Infinity and +Infinity
|
||||
// we do not support -Infinity and +Infinity
|
||||
// we assume that there is always NaN
|
||||
|
||||
SetZero();
|
||||
SetNaN();
|
||||
}
|
||||
else
|
||||
if( e > 0 )
|
||||
|
@ -2227,12 +2234,19 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
if( IsNan() )
|
||||
{
|
||||
result = ToDouble_SetDouble( false, 2047, 0, false, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sint e_correction = sint(man*TTMATH_BITS_PER_UINT) - 1;
|
||||
|
||||
if( exponent >= 1024 - e_correction )
|
||||
{
|
||||
// +/- infinity
|
||||
result = ToDouble_SetDouble( IsSign(), 2047, 0, true);
|
||||
result = ToDouble_SetDouble( 0, 2047, 0, true);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -2267,7 +2281,7 @@ private:
|
|||
#ifdef TTMATH_PLATFORM32
|
||||
|
||||
// 32bit platforms
|
||||
double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false) const
|
||||
double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
|
||||
{
|
||||
union
|
||||
{
|
||||
|
@ -2282,6 +2296,12 @@ private:
|
|||
|
||||
temp.u[1] |= (e << 20) & 0x7FF00000u;
|
||||
|
||||
if( nan )
|
||||
{
|
||||
temp.u[0] |= 1;
|
||||
return temp.d;
|
||||
}
|
||||
|
||||
if( infinity )
|
||||
return temp.d;
|
||||
|
||||
|
@ -2304,7 +2324,7 @@ private:
|
|||
#else
|
||||
|
||||
// 64bit platforms
|
||||
double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false) const
|
||||
double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
|
||||
{
|
||||
union
|
||||
{
|
||||
|
@ -2319,6 +2339,12 @@ private:
|
|||
|
||||
temp.u |= (e << 52) & 0x7FF0000000000000ul;
|
||||
|
||||
if( nan )
|
||||
{
|
||||
temp.u |= 1;
|
||||
return temp.d;
|
||||
}
|
||||
|
||||
if( infinity )
|
||||
return temp.d;
|
||||
|
||||
|
@ -3088,7 +3114,7 @@ private:
|
|||
else
|
||||
was_carry = false;
|
||||
|
||||
new_man[i] = UInt<man>::DigitToChar( digit );
|
||||
new_man[i] = static_cast<char>( UInt<man>::DigitToChar(digit) );
|
||||
}
|
||||
|
||||
if( i<0 && was_carry )
|
||||
|
|
|
@ -1316,5 +1316,4 @@ public:
|
|||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* This file is a part of TTMath Mathematical Library
|
||||
* This file is a part of TTMath Bignum Library
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
||||
*/
|
||||
|
@ -984,7 +984,7 @@ void Not(int sindex, int amount_of_args, ValueType & result)
|
|||
|
||||
void DegToRad(int sindex, int amount_of_args, ValueType & result)
|
||||
{
|
||||
ErrorCode err;
|
||||
ErrorCode err = err_ok;
|
||||
|
||||
if( amount_of_args == 1 )
|
||||
{
|
||||
|
@ -1063,7 +1063,7 @@ void RadToGrad(int sindex, int amount_of_args, ValueType & result)
|
|||
|
||||
void DegToGrad(int sindex, int amount_of_args, ValueType & result)
|
||||
{
|
||||
ErrorCode err;
|
||||
ErrorCode err = err_ok;
|
||||
|
||||
if( amount_of_args == 1 )
|
||||
{
|
||||
|
@ -1566,7 +1566,7 @@ int character;
|
|||
|
||||
do
|
||||
{
|
||||
result += character;
|
||||
result += static_cast<char>( character );
|
||||
character = * ++pstring;
|
||||
}
|
||||
while( (character>='a' && character<='z') ||
|
||||
|
|
|
@ -360,7 +360,7 @@ namespace ttmath
|
|||
foo.Add(foo);
|
||||
but there are only few methods which can do that
|
||||
*/
|
||||
class ReferenceError : public std::logic_error, ExceptionInfo
|
||||
class ReferenceError : public std::logic_error, public ExceptionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -392,7 +392,7 @@ namespace ttmath
|
|||
the name and the line of a file where the macro TTMATH_ASSERT
|
||||
was used)
|
||||
*/
|
||||
class RuntimeError : public std::runtime_error, ExceptionInfo
|
||||
class RuntimeError : public std::runtime_error, public ExceptionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#ifndef headerfilettmathuint
|
||||
#define headerfilettmathuint
|
||||
|
||||
|
||||
/*!
|
||||
\file ttmathuint.h
|
||||
\brief template class UInt<uint>
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
#include "ttmathtypes.h"
|
||||
|
||||
|
||||
|
@ -1813,7 +1815,7 @@ private:
|
|||
|
||||
if( Div2_DivisorGreaterOrEqual( divisor, remainder,
|
||||
table_id, index,
|
||||
divisor_table_id, divisor_index) )
|
||||
divisor_index) )
|
||||
{
|
||||
TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
|
||||
return 0;
|
||||
|
@ -1833,7 +1835,7 @@ private:
|
|||
bool Div2_DivisorGreaterOrEqual( const UInt<value_size> & divisor,
|
||||
UInt<value_size> * remainder,
|
||||
uint table_id, uint index,
|
||||
uint divisor_table_id, uint divisor_index )
|
||||
uint divisor_index )
|
||||
{
|
||||
if( divisor_index > index )
|
||||
{
|
||||
|
@ -2706,7 +2708,7 @@ public:
|
|||
do
|
||||
{
|
||||
temp.DivInt(b, &rem);
|
||||
character = DigitToChar( rem );
|
||||
character = static_cast<char>( DigitToChar(rem) );
|
||||
result.insert(result.begin(), character);
|
||||
}
|
||||
while( !temp.IsZero() );
|
||||
|
|
|
@ -105,13 +105,13 @@ namespace ttmath
|
|||
mov eax,[c]
|
||||
neg eax // CF=1 if rax!=0 , CF=0 if rax==0
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
mov eax,[esi+edx*4]
|
||||
adc [ebx+edx*4],eax
|
||||
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
@ -204,16 +204,16 @@ namespace ttmath
|
|||
|
||||
mov eax, [value]
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
add [ebx+edx*4], eax
|
||||
jnc end
|
||||
jnc ttmath_end
|
||||
|
||||
mov eax, 1
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
end:
|
||||
ttmath_end:
|
||||
setc al
|
||||
movzx edx, al
|
||||
mov [c], edx
|
||||
|
@ -321,16 +321,16 @@ namespace ttmath
|
|||
|
||||
mov eax, [x2]
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
adc [ebx+edx*4], eax
|
||||
jnc end
|
||||
jnc ttmath_end
|
||||
|
||||
mov eax, 0
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
end:
|
||||
ttmath_end:
|
||||
setc al
|
||||
movzx edx, al
|
||||
mov [c], edx
|
||||
|
@ -423,36 +423,37 @@ namespace ttmath
|
|||
mov ebx, [ss2]
|
||||
mov edi, [result]
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
mov eax, [esi+edx*4]
|
||||
adc eax, [ebx+edx*4]
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
adc ecx, ecx // ecx has the cf state
|
||||
|
||||
mov ebx, [rest]
|
||||
or ebx, ebx
|
||||
jz end
|
||||
jz ttmath_end
|
||||
|
||||
xor ebx, ebx // ebx = 0
|
||||
neg ecx // setting cf from ecx
|
||||
mov ecx, [rest] // ecx is != 0
|
||||
p2:
|
||||
|
||||
ttmath_loop2:
|
||||
mov eax, [esi+edx*4]
|
||||
adc eax, ebx
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p2
|
||||
jnz ttmath_loop2
|
||||
|
||||
adc ecx, ecx
|
||||
|
||||
end:
|
||||
ttmath_end:
|
||||
mov [c], ecx
|
||||
|
||||
popad
|
||||
|
@ -548,13 +549,13 @@ namespace ttmath
|
|||
mov eax,[c]
|
||||
neg eax // CF=1 if rax!=0 , CF=0 if rax==0
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
mov eax,[esi+edx*4]
|
||||
sbb [ebx+edx*4],eax
|
||||
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
@ -646,16 +647,16 @@ namespace ttmath
|
|||
|
||||
mov eax, [value]
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
sub [ebx+edx*4], eax
|
||||
jnc end
|
||||
jnc ttmath_end
|
||||
|
||||
mov eax, 1
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
end:
|
||||
ttmath_end:
|
||||
setc al
|
||||
movzx edx, al
|
||||
mov [c], edx
|
||||
|
@ -750,36 +751,37 @@ namespace ttmath
|
|||
mov ebx, [ss2]
|
||||
mov edi, [result]
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
mov eax, [esi+edx*4]
|
||||
sbb eax, [ebx+edx*4]
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
adc ecx, ecx // ecx has the cf state
|
||||
|
||||
mov ebx, [rest]
|
||||
or ebx, ebx
|
||||
jz end
|
||||
jz ttmath_end
|
||||
|
||||
xor ebx, ebx // ebx = 0
|
||||
neg ecx // setting cf from ecx
|
||||
mov ecx, [rest] // ecx is != 0
|
||||
p2:
|
||||
|
||||
ttmath_loop2:
|
||||
mov eax, [esi+edx*4]
|
||||
sbb eax, ebx
|
||||
mov [edi+edx*4], eax
|
||||
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p2
|
||||
jnz ttmath_loop2
|
||||
|
||||
adc ecx, ecx
|
||||
|
||||
end:
|
||||
ttmath_end:
|
||||
mov [c], ecx
|
||||
|
||||
popad
|
||||
|
@ -870,12 +872,12 @@ namespace ttmath
|
|||
neg ecx
|
||||
mov ecx, [b]
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
rcl dword ptr [ebx+edx*4], 1
|
||||
|
||||
inc edx
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
@ -946,11 +948,11 @@ namespace ttmath
|
|||
neg ecx
|
||||
mov ecx, [b]
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
rcr dword ptr [ebx+ecx*4-4], 1
|
||||
|
||||
dec ecx
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
adc ecx, ecx
|
||||
mov [c], ecx
|
||||
|
@ -1045,7 +1047,7 @@ namespace ttmath
|
|||
or eax, eax
|
||||
cmovnz esi, ebp // if(c) esi=mask else esi=0
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
rol dword ptr [ebx+edx*4], cl
|
||||
|
||||
mov eax, [ebx+edx*4]
|
||||
|
@ -1056,7 +1058,7 @@ namespace ttmath
|
|||
|
||||
inc edx
|
||||
dec edi
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
pop ebp // restoring ebp
|
||||
|
||||
|
@ -1175,7 +1177,7 @@ namespace ttmath
|
|||
or eax, eax
|
||||
cmovnz esi, ebp // if(c) esi=mask else esi=0
|
||||
|
||||
p:
|
||||
ttmath_loop:
|
||||
ror dword ptr [ebx+edx*4], cl
|
||||
|
||||
mov eax, [ebx+edx*4]
|
||||
|
@ -1186,7 +1188,7 @@ namespace ttmath
|
|||
|
||||
dec edx
|
||||
dec edi
|
||||
jnz p
|
||||
jnz ttmath_loop
|
||||
|
||||
pop ebp // restoring ebp
|
||||
|
||||
|
|
Loading…
Reference in New Issue