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::BigAnd() Big::BigOr() Big::BigXor() should have set NaN
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;
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)
* 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
(and only for GCC and MS VC compilers)
* removed: macro TTMATH_RELEASE

View File

@ -275,7 +275,7 @@ public:
mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;
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)
{
if( value == 0 )
{
SetZero();
return;
}
info = 0;
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
/*!

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

View File

@ -131,8 +131,8 @@ namespace ttmath
for example:
"1+2;4+5"
the result will be on the stack as follows:
"3"
"9"
stack[0].value=3
stack[1].value=9
*/
template<class ValueType>
class Parser
@ -282,9 +282,16 @@ public:
/*!
stack on which we're keeping the Items
at the end of parsing we'll have the result on its
the result don't have to be one value, it can be a list
of values separated by the 'semicolon item'
at the end of parsing we'll have the result here
the result don't have to be one value, it can be
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;
@ -2715,7 +2722,9 @@ ErrorCode Parse(const wchar_t * 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 <vector>
#ifndef _MSC_VER
#include <stdint.h>
// for uint64_t and int64_t on a 32 bit platform
#endif
/*!
the version of the library
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)
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 9
#define TTMATH_REVISION_VER 2
#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 _M_X64 && !defined __x86_64__
@ -81,16 +91,12 @@
so you should set TTMATH_PLATFORMxx manually
*/
/*!
we're using a 32bit platform
*/
// we're using a 32bit platform
#define TTMATH_PLATFORM32
#else
/*!
we're using a 64bit platform
*/
// we're using a 64bit platform
#define TTMATH_PLATFORM64
#endif
@ -98,35 +104,44 @@
#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
/*!
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++
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
*/
#ifndef TTMATH_FORCEASM
amd64 architecture:
__x86_64__ defined by GNU C and Sun Studio
_M_X64 defined by Visual Studio
#if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
/*!
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
#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
{
@ -140,17 +155,18 @@ namespace ttmath
typedef signed int sint;
/*!
this type is twice bigger than uint
(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
on 32 bit platform ulint and slint will be equal 64 bits
*/
#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 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
/*!
@ -198,13 +214,8 @@ namespace ttmath
#endif
/*!
on 64bit platform we do not define ulint
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
on 64bit platforms we do not define ulint and slint
*/
//typedef unsigned long long int ulint;
/*!
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
@ -2805,6 +2852,8 @@ public:
return table[0];
}
// !! add a second version of ToUInt() with an reference (pointer) to the output value
// and with returning carry
private:

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* Copyright (c) 2006-2010, Tomasz Sowa
* All rights reserved.
*
* 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
*/
#ifdef _MSC_VER
#ifndef __GNUC__
#include <intrin.h>
#endif
@ -59,7 +59,7 @@
namespace ttmath
{
#ifdef _MSC_VER
#ifndef __GNUC__
extern "C"
{
@ -92,7 +92,7 @@ namespace ttmath
template<uint value_size>
const char * UInt<value_size>::LibTypeStr()
{
#ifdef _MSC_VER
#ifndef __GNUC__
static const char info[] = "asm_vc_64";
#endif
@ -110,7 +110,7 @@ namespace ttmath
template<uint value_size>
LibTypeCode UInt<value_size>::LibType()
{
#ifdef _MSC_VER
#ifndef __GNUC__
LibTypeCode info = asm_vc_64;
#endif
@ -149,11 +149,7 @@ namespace ttmath
// we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it
#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_adc_x64(p1,p2,b,c);
#endif
@ -220,12 +216,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size )
#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_addindexed_x64(p1,b,index,value);
#endif
@ -304,12 +295,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size - 1 )
#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_addindexed2_x64(p1,b,index,x1,x2);
#endif
@ -378,12 +364,7 @@ namespace ttmath
uint c;
#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_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
#endif
@ -456,16 +437,10 @@ namespace ttmath
uint * p1 = table;
const uint * p2 = ss2.table;
// we don't have to use TTMATH_REFERENCE_ASSERT here
// this algorithm doesn't require it
#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_sbb_x64(p1,p2,b,c);
#endif
@ -529,12 +504,7 @@ namespace ttmath
TTMATH_ASSERT( index < value_size )
#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_subindexed_x64(p1,b,index,value);
#endif
@ -599,12 +569,7 @@ namespace ttmath
uint c;
#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_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
#endif
@ -680,14 +645,9 @@ namespace ttmath
{
sint b = value_size;
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);
#endif
@ -742,12 +702,7 @@ namespace ttmath
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_rcr_x64(p1,b,c);
#endif
@ -803,12 +758,7 @@ namespace ttmath
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_rcl2_x64(p1,b,bits,c);
#endif
@ -880,12 +830,8 @@ namespace ttmath
sint b = value_size;
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_rcr2_x64(p1,b,bits,c);
#endif
@ -949,13 +895,8 @@ namespace ttmath
{
sint result;
#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__
unsigned long nIndex = 0;
@ -998,13 +939,8 @@ namespace ttmath
{
sint result;
#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__
unsigned long nIndex = 0;
@ -1057,12 +993,8 @@ namespace ttmath
uint old_bit;
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
#ifdef _MSC_VER
#ifndef __GNUC__
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
#endif
@ -1118,12 +1050,8 @@ namespace ttmath
uint result1_;
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
#ifdef _MSC_VER
#ifndef __GNUC__
result1_ = _umul128(a,b,&result2_);
#endif
@ -1181,12 +1109,8 @@ namespace ttmath
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
#ifdef _MSC_VER
#ifndef __GNUC__
ttmath_div_x64(&a,&b,c);
r_ = a;