diff --git a/CHANGELOG b/CHANGELOG index 670d051..08d01b5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index a6d181c..bc7a219 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -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> 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 & 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 & operator=(slint value) + { + FromInt(value); + + return *this; + } + +#endif + + + #ifdef TTMATH_PLATFORM64 /*! diff --git a/ttmath/ttmathint.h b/ttmath/ttmathint.h index 4b630fd..dbe14a2 100644 --- a/ttmath/ttmathint.h +++ b/ttmath/ttmathint.h @@ -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::table[0] = (uint)(ulint)n; + + if( value_size == 1 ) + { + if( uint(ulint(n) >> 32) != mask ) + return 1; + + return ((UInt::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1; + } + + UInt::table[1] = (uint)(ulint(n) >> 32); + + for(uint i=2 ; i::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 & 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 diff --git a/ttmath/ttmathparser.h b/ttmath/ttmathparser.h index 2e9983b..1b3ed91 100644 --- a/ttmath/ttmathparser.h +++ b/ttmath/ttmathparser.h @@ -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 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 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 } diff --git a/ttmath/ttmathtypes.h b/ttmath/ttmathtypes.h index 72222e2..a4dce94 100644 --- a/ttmath/ttmathtypes.h +++ b/ttmath/ttmathtypes.h @@ -56,22 +56,32 @@ #include #include +#ifndef _MSC_VER +#include +// 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 diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index 8eda5bd..892a2cc 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -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 & 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: diff --git a/ttmath/ttmathuint_x86_64.h b/ttmath/ttmathuint_x86_64.h index 2fedb70..188fc5e 100644 --- a/ttmath/ttmathuint_x86_64.h +++ b/ttmath/ttmathuint_x86_64.h @@ -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 #endif @@ -59,7 +59,7 @@ namespace ttmath { - #ifdef _MSC_VER + #ifndef __GNUC__ extern "C" { @@ -92,7 +92,7 @@ namespace ttmath template const char * UInt::LibTypeStr() { - #ifdef _MSC_VER + #ifndef __GNUC__ static const char info[] = "asm_vc_64"; #endif @@ -110,7 +110,7 @@ namespace ttmath template LibTypeCode UInt::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;