added: on 32bit platforms:

uint UInt::FromUInt(uint64_t n)
        uint Int::FromInt(int64_t n)
        void Big::FromUInt(uint64_t n)
        void Big::FromInt(int64_t n)        
        and appropriate constructors and operators
added:  TTMATH_FORCEASM macro
        asm version of the library is available by default only for:
        x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
        but you can force using asm version (the same asm as for Microsoft Visual)
        by defining TTMATH_FORCEASM macro
        you have to be sure that your compiler accept such an asm format
                        


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@311 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2010-09-19 17:23:39 +00:00
parent b6fe168e3c
commit 90674c9505
7 changed files with 343 additions and 153 deletions

View File

@ -1,4 +1,4 @@
Version 0.9.2 prerelease (2010.09.18): Version 0.9.2 prerelease (2010.09.19):
* fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa * fixed: Big::Add() sometimes incorrectly rounded the last bit from its mantissa
* fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN * fixed: Big::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
when the argument was negative (they only returned 2) when the argument was negative (they only returned 2)
@ -38,6 +38,18 @@ Version 0.9.2 prerelease (2010.09.18):
Big<1, 2> var; Big<1, 2> var;
var.mantissa and var.exponent will be set to zero var.mantissa and var.exponent will be set to zero
(but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes) (but var has the NaN flag set too - it is not zero value, this is mainly for debug purposes)
* added: only on 32bit platforms:
uint UInt::FromUInt(uint64_t n)
uint Int::FromInt(int64_t n)
void Big::FromUInt(uint64_t n)
void Big::FromInt(int64_t n)
and appropriate constructors and operators
* added: TTMATH_FORCEASM macro
asm version of the library is available by default only for:
x86 and amd64 platforms and for Microsoft Visual and GCC compilers,
but you can force using asm version (the same asm as for Microsoft Visual)
by defining TTMATH_FORCEASM macro
you have to be sure that your compiler accept such an asm format
* changed: now asm version is available only on x86 and amd64 * changed: now asm version is available only on x86 and amd64
(and only for GCC and MS VC compilers) (and only for GCC and MS VC compilers)
* removed: macro TTMATH_RELEASE * removed: macro TTMATH_RELEASE

View File

@ -275,7 +275,7 @@ public:
mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT; mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;
exponent = -sint(man * TTMATH_BITS_PER_UINT - 1); exponent = -sint(man * TTMATH_BITS_PER_UINT - 1);
// don't have to Standardize() - the last bit is set // don't have to Standardize() - the last bit from mantissa is set
} }
@ -2354,6 +2354,12 @@ public:
*/ */
void FromUInt(uint value) void FromUInt(uint value)
{ {
if( value == 0 )
{
SetZero();
return;
}
info = 0; info = 0;
for(uint i=0 ; i<man-1 ; ++i) for(uint i=0 ; i<man-1 ; ++i)
@ -2840,6 +2846,130 @@ public:
} }
#ifdef TTMATH_PLATFORM32
/*!
a method for converting 'ulint' (64bit unsigned integer) to this class
*/
void FromUInt(ulint value)
{
if( value == 0 )
{
SetZero();
return;
}
info = 0;
if( man == 1 )
{
sint bit = mantissa.FindLeadingBitInWord(uint(value >> 32));
if( bit != -1 )
{
// the highest word from value is different from zero
bit += 1;
value >>= bit;
exponent = bit;
}
else
{
exponent.SetZero();
}
mantissa.table[0] = uint(value);
}
else
{
#ifdef _MSC_VER
//warning C4307: '*' : integral constant overflow
#pragma warning( disable: 4307 )
#endif
// man >= 2
mantissa.table[man-1] = uint(value >> 32);
mantissa.table[man-2] = uint(value);
#ifdef _MSC_VER
//warning C4307: '*' : integral constant overflow
#pragma warning( default: 4307 )
#endif
exponent = -sint(man-2) * sint(TTMATH_BITS_PER_UINT);
for(uint i=0 ; i<man-2 ; ++i)
mantissa.table[i] = 0;
}
// there shouldn't be a carry because 'value' has the 'ulint' type
// (we have sufficient exponent)
Standardizing();
}
/*!
a method for converting 'slint' (64bit signed integer) to this class
*/
void FromInt(slint value)
{
bool is_sign = false;
if( value < 0 )
{
value = -value;
is_sign = true;
}
FromUInt(ulint(value));
if( is_sign )
SetSign();
}
/*!
a constructor for converting 'ulint' (64bit unsigned integer) to this class
*/
Big(ulint value)
{
FromUInt(value);
}
/*!
an operator for converting 'ulint' (64bit unsigned integer) to this class
*/
Big<exp, man> & operator=(ulint value)
{
FromUInt(value);
return *this;
}
/*!
a constructor for converting 'slint' (64bit signed integer) to this class
*/
Big(slint value)
{
FromInt(value);
}
/*!
an operator for converting 'slint' (64bit signed integer) to this class
*/
Big<exp, man> & operator=(slint value)
{
FromInt(value);
return *this;
}
#endif
#ifdef TTMATH_PLATFORM64 #ifdef TTMATH_PLATFORM64
/*! /*!

View File

@ -858,6 +858,61 @@ public:
#ifdef TTMATH_PLATFORM32
/*!
this method converts signed 64 bit int type to this class
***this method is created only on a 32bit platform***
*/
uint FromInt(slint n)
{
uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0;
UInt<value_size>::table[0] = (uint)(ulint)n;
if( value_size == 1 )
{
if( uint(ulint(n) >> 32) != mask )
return 1;
return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
}
UInt<value_size>::table[1] = (uint)(ulint(n) >> 32);
for(uint i=2 ; i<value_size ; ++i)
UInt<value_size>::table[i] = mask;
return 0;
}
/*!
this operator converts signed 64 bit int type to this class
***this operator is created only on a 32bit platform***
*/
Int<value_size> & operator=(slint n)
{
FromInt(n);
return *this;
}
/*!
a constructor for converting signed 64 bit int to this class
***this constructor is created only on a 32bit platform***
*/
Int(slint n)
{
FromInt(n);
}
#endif
#ifdef TTMATH_PLATFORM64 #ifdef TTMATH_PLATFORM64

View File

@ -131,8 +131,8 @@ namespace ttmath
for example: for example:
"1+2;4+5" "1+2;4+5"
the result will be on the stack as follows: the result will be on the stack as follows:
"3" stack[0].value=3
"9" stack[1].value=9
*/ */
template<class ValueType> template<class ValueType>
class Parser class Parser
@ -282,9 +282,16 @@ public:
/*! /*!
stack on which we're keeping the Items stack on which we're keeping the Items
at the end of parsing we'll have the result on its at the end of parsing we'll have the result here
the result don't have to be one value, it can be a list the result don't have to be one value, it can be
of values separated by the 'semicolon item' more than one if we have used a semicolon in the global space
e.g. such input string "1+2;3+4" will generate a result:
stack[0].value=3
stack[1].value=7
you should check if the stack is not empty, because if there was
a syntax error in the input string then we do not have any results
on the stack
*/ */
std::vector<Item> stack; std::vector<Item> stack;
@ -2715,7 +2722,9 @@ ErrorCode Parse(const wchar_t * str)
{ {
Misc::AssignString(wide_to_ansi, str); Misc::AssignString(wide_to_ansi, str);
return Parse(wide_to_ansi.c_str()); return Parse(wide_to_ansi.c_str());
// !! wide_to_ansi clearing can be added here
} }

View File

@ -56,22 +56,32 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#ifndef _MSC_VER
#include <stdint.h>
// for uint64_t and int64_t on a 32 bit platform
#endif
/*! /*!
the version of the library the version of the library
TTMATH_PRERELEASE_VER is either zero or one TTMATH_PRERELEASE_VER is either zero or one
if zero that means this is the release version of the library zero means that this is the release version of the library
(one means something like beta) (one means something like beta)
*/ */
#define TTMATH_MAJOR_VER 0 #define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 9 #define TTMATH_MINOR_VER 9
#define TTMATH_REVISION_VER 2 #define TTMATH_REVISION_VER 2
#define TTMATH_PRERELEASE_VER 1 #define TTMATH_PRERELEASE_VER 1
/*!
you can define a platform explicitly by defining either
TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
*/
#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64 #if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
#if !defined _M_X64 && !defined __x86_64__ #if !defined _M_X64 && !defined __x86_64__
@ -81,16 +91,12 @@
so you should set TTMATH_PLATFORMxx manually so you should set TTMATH_PLATFORMxx manually
*/ */
/*! // we're using a 32bit platform
we're using a 32bit platform
*/
#define TTMATH_PLATFORM32 #define TTMATH_PLATFORM32
#else #else
/*! // we're using a 64bit platform
we're using a 64bit platform
*/
#define TTMATH_PLATFORM64 #define TTMATH_PLATFORM64
#endif #endif
@ -98,35 +104,44 @@
#endif #endif
/*!
asm version of the library is available by default only for:
x86 and amd64 platforms and for Microsoft Visual and GCC compilers
#if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64 but you can force using asm version (the same asm as for Microsoft Visual)
/*! by defining TTMATH_FORCEASM macro
x86 architecture: you have to be sure that your compiler accept such an asm format
__i386__ defined by GNU C */
_X86_ defined by MinGW32 #ifndef TTMATH_FORCEASM
_M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
amd64 architecture: #if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
__x86_64__ defined by GNU C and Sun Studio /*!
_M_X64 defined by Visual Studio x86 architecture:
__i386__ defined by GNU C
_X86_ defined by MinGW32
_M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
amd64 architecture:
__x86_64__ defined by GNU C and Sun Studio
_M_X64 defined by Visual Studio
asm version is available only for x86 or amd64 platforms
*/
#define TTMATH_NOASM
#endif
#if !defined _MSC_VER && !defined __GNUC__
/*!
another compilers than MS VC or GCC by default use no asm version
*/
#define TTMATH_NOASM
#endif
asm version is available only for x86 or amd64 platforms
*/
#define TTMATH_NOASM
#endif #endif
#if !defined _MSC_VER && !defined __GNUC__
/*!
another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
*/
#define TTMATH_NOASM
#endif
namespace ttmath namespace ttmath
{ {
@ -140,17 +155,18 @@ namespace ttmath
typedef signed int sint; typedef signed int sint;
/*! /*!
this type is twice bigger than uint on 32 bit platform ulint and slint will be equal 64 bits
(64bit on a 32bit platforms)
although C++ Standard - ANSI ISO IEC 14882:2003 doesn't define such a type (long long)
but it is defined in C99 and in upcoming C++0x /3.9.1 (2)/ and many compilers support it
this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
but only on a 32bit platform
*/ */
#ifdef TTMATH_NOASM #ifdef _MSC_VER
// long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
// stdint.h is not available on Visual Studio prior to VS 2010 version
typedef unsigned long long int ulint; typedef unsigned long long int ulint;
typedef signed long long int slint;
#else
// we do not use 'long' here because there is a difference in unix and windows
// environments: in unix 'long' has 64 bits but in windows it has only 32 bits
typedef uint64_t ulint;
typedef int64_t slint;
#endif #endif
/*! /*!
@ -198,13 +214,8 @@ namespace ttmath
#endif #endif
/*! /*!
on 64bit platform we do not define ulint on 64bit platforms we do not define ulint and slint
sizeof(long long) is 8 (64bit) but we need 128bit
on 64 bit platform (when there is defined TTMATH_NOASM macro)
methods UInt::MulTwoWords and UInt::DivTwoWords are using other algorithms than those on 32 bit
*/ */
//typedef unsigned long long int ulint;
/*! /*!
how many bits there are in the uint type how many bits there are in the uint type

View File

@ -2618,6 +2618,53 @@ public:
} }
#ifdef TTMATH_PLATFORM32
/*!
this method converts unsigned 64 bit int type to this class
***this method is created only on a 32bit platform***
*/
uint FromUInt(ulint n)
{
table[0] = (uint)n;
if( value_size == 1 )
return (n <= ulint(TTMATH_UINT_MAX_VALUE)) ? 0 : 1;
table[1] = (uint)(n >> 32);
for(uint i=2 ; i<value_size ; ++i)
table[i] = 0;
return 0;
}
/*!
this operator converts unsigned 64 bit int type to this class
***this operator is created only on a 32bit platform***
*/
UInt<value_size> & operator=(ulint n)
{
FromUInt(n);
return *this;
}
/*!
a constructor for converting unsigned 64 bit int to this class
***this constructor is created only on a 32bit platform***
*/
UInt(ulint n)
{
FromUInt(n);
}
#endif
#ifdef TTMATH_PLATFORM64 #ifdef TTMATH_PLATFORM64
@ -2805,6 +2852,8 @@ public:
return table[0]; return table[0];
} }
// !! add a second version of ToUInt() with an reference (pointer) to the output value
// and with returning carry
private: private:

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2006-2009, Tomasz Sowa * Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -51,7 +51,7 @@
this file is included at the end of ttmathuint.h this file is included at the end of ttmathuint.h
*/ */
#ifdef _MSC_VER #ifndef __GNUC__
#include <intrin.h> #include <intrin.h>
#endif #endif
@ -59,7 +59,7 @@
namespace ttmath namespace ttmath
{ {
#ifdef _MSC_VER #ifndef __GNUC__
extern "C" extern "C"
{ {
@ -92,7 +92,7 @@ namespace ttmath
template<uint value_size> template<uint value_size>
const char * UInt<value_size>::LibTypeStr() const char * UInt<value_size>::LibTypeStr()
{ {
#ifdef _MSC_VER #ifndef __GNUC__
static const char info[] = "asm_vc_64"; static const char info[] = "asm_vc_64";
#endif #endif
@ -110,7 +110,7 @@ namespace ttmath
template<uint value_size> template<uint value_size>
LibTypeCode UInt<value_size>::LibType() LibTypeCode UInt<value_size>::LibType()
{ {
#ifdef _MSC_VER #ifndef __GNUC__
LibTypeCode info = asm_vc_64; LibTypeCode info = asm_vc_64;
#endif #endif
@ -149,11 +149,7 @@ namespace ttmath
// we don't have to use TTMATH_REFERENCE_ASSERT here // we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it // this algorithm doesn't require it
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_adc_x64(p1,p2,b,c); c = ttmath_adc_x64(p1,p2,b,c);
#endif #endif
@ -220,12 +216,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size ) TTMATH_ASSERT( index < value_size )
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_addindexed_x64(p1,b,index,value); c = ttmath_addindexed_x64(p1,b,index,value);
#endif #endif
@ -304,12 +295,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size - 1 ) TTMATH_ASSERT( index < value_size - 1 )
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_addindexed2_x64(p1,b,index,x1,x2); c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
#endif #endif
@ -378,12 +364,7 @@ namespace ttmath
uint c; uint c;
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result); c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
#endif #endif
@ -456,16 +437,10 @@ namespace ttmath
uint * p1 = table; uint * p1 = table;
const uint * p2 = ss2.table; const uint * p2 = ss2.table;
// we don't have to use TTMATH_REFERENCE_ASSERT here // we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it // this algorithm doesn't require it
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_sbb_x64(p1,p2,b,c); c = ttmath_sbb_x64(p1,p2,b,c);
#endif #endif
@ -529,12 +504,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size ) TTMATH_ASSERT( index < value_size )
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_subindexed_x64(p1,b,index,value); c = ttmath_subindexed_x64(p1,b,index,value);
#endif #endif
@ -599,12 +569,7 @@ namespace ttmath
uint c; uint c;
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result); c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
#endif #endif
@ -680,14 +645,9 @@ namespace ttmath
{ {
sint b = value_size; sint b = value_size;
uint * p1 = table; uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER #ifndef __GNUC__
c = ttmath_rcl_x64(p1,b,c); c = ttmath_rcl_x64(p1,b,c);
#endif #endif
@ -742,12 +702,7 @@ namespace ttmath
uint * p1 = table; uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_rcr_x64(p1,b,c); c = ttmath_rcr_x64(p1,b,c);
#endif #endif
@ -803,12 +758,7 @@ namespace ttmath
uint * p1 = table; uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
c = ttmath_rcl2_x64(p1,b,bits,c); c = ttmath_rcl2_x64(p1,b,bits,c);
#endif #endif
@ -880,12 +830,8 @@ namespace ttmath
sint b = value_size; sint b = value_size;
uint * p1 = table; uint * p1 = table;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifndef __GNUC__
#ifdef _MSC_VER
c = ttmath_rcr2_x64(p1,b,bits,c); c = ttmath_rcr2_x64(p1,b,bits,c);
#endif #endif
@ -949,13 +895,8 @@ namespace ttmath
{ {
sint result; sint result;
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
unsigned long nIndex = 0; unsigned long nIndex = 0;
@ -998,13 +939,8 @@ namespace ttmath
{ {
sint result; sint result;
#if !defined(__GNUC__) && !defined(_MSC_VER) #ifndef __GNUC__
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifdef _MSC_VER
unsigned long nIndex = 0; unsigned long nIndex = 0;
@ -1057,12 +993,8 @@ namespace ttmath
uint old_bit; uint old_bit;
uint v = value; uint v = value;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifndef __GNUC__
#ifdef _MSC_VER
old_bit = _bittestandset64((__int64*)&value,bit) != 0; old_bit = _bittestandset64((__int64*)&value,bit) != 0;
#endif #endif
@ -1118,12 +1050,8 @@ namespace ttmath
uint result1_; uint result1_;
uint result2_; uint result2_;
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifndef __GNUC__
#ifdef _MSC_VER
result1_ = _umul128(a,b,&result2_); result1_ = _umul128(a,b,&result2_);
#endif #endif
@ -1181,12 +1109,8 @@ namespace ttmath
TTMATH_ASSERT( c != 0 ) TTMATH_ASSERT( c != 0 )
#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
#endif
#ifndef __GNUC__
#ifdef _MSC_VER
ttmath_div_x64(&a,&b,c); ttmath_div_x64(&a,&b,c);
r_ = a; r_ = a;