Compare commits
51 Commits
Author | SHA1 | Date |
---|---|---|
Tomasz Sowa | aad580f51e | |
Tomasz Sowa | 3b113374b7 | |
Tomasz Sowa | 0f2fcaf547 | |
Tomasz Sowa | f88cba2688 | |
Tomasz Sowa | 48d694a47f | |
Tomasz Sowa | 9a93db39c4 | |
Tomasz Sowa | f98c434fc4 | |
Tomasz Sowa | 132fa10cd4 | |
Tomasz Sowa | dcdb1db9ec | |
Tomasz Sowa | d93d5ffd74 | |
Tomasz Sowa | 9b279276f2 | |
Tomasz Sowa | 83b5ab7170 | |
Tomasz Sowa | 35333b1e32 | |
Tomasz Sowa | c73af9c116 | |
Tomasz Sowa | f06592376f | |
Tomasz Sowa | b36821024b | |
Tomasz Sowa | cd740c5924 | |
Tomasz Sowa | 46ed8c3108 | |
Tomasz Sowa | f4f7882387 | |
Tomasz Sowa | 86dc01cdee | |
Tomasz Sowa | 2067301d1c | |
Tomasz Sowa | e2cdeac423 | |
Tomasz Sowa | 5893ffa9e3 | |
Tomasz Sowa | b862422bd9 | |
Tomasz Sowa | cb15ac0cd8 | |
Tomasz Sowa | 77c41e644a | |
Tomasz Sowa | 506840787a | |
Tomasz Sowa | e58253a078 | |
Tomasz Sowa | 6862321fad | |
Tomasz Sowa | 2e192969b0 | |
Tomasz Sowa | e8daa77d75 | |
Tomasz Sowa | 231164f6ea | |
Tomasz Sowa | c51b2fdcc9 | |
Tomasz Sowa | 84f34ebe52 | |
Tomasz Sowa | 3190f3011f | |
Tomasz Sowa | a34cf55155 | |
Tomasz Sowa | 648de47400 | |
Tomasz Sowa | 362207e2f1 | |
Tomasz Sowa | a40e951923 | |
Tomasz Sowa | b028896118 | |
Tomasz Sowa | a67a088e3a | |
Tomasz Sowa | 996fac15f1 | |
Tomasz Sowa | 1e268f1808 | |
Tomasz Sowa | 90674c9505 | |
Tomasz Sowa | b6fe168e3c | |
Tomasz Sowa | ae61b302a8 | |
Tomasz Sowa | a1c41c02db | |
Tomasz Sowa | 69f065245e | |
Tomasz Sowa | c65dac524a | |
Tomasz Sowa | b3c3dd8c3f | |
Tomasz Sowa | 1b7e13a9fd |
122
CHANGELOG
122
CHANGELOG
|
@ -1,3 +1,125 @@
|
||||||
|
Version 0.9.4_prerelease (....):
|
||||||
|
* fixed: cannot compile on MS Windows when compiling with GCC (Mingw) for 64 bit platform:
|
||||||
|
incorrect size of ttmath::uint and ::sint were used
|
||||||
|
they were 'long' but 'long' is a 32bit type on Windows
|
||||||
|
* fixed: a crash in Big::Add() (buffer overflow)
|
||||||
|
there was an offset calculated from Int type by using Abs() method and a carry was not checked
|
||||||
|
(if there is a carry we should not make addition -- the argument is too small)
|
||||||
|
this had no impact on calculated values because there was a crash (bus error) immediately
|
||||||
|
following program could crash (64bit):
|
||||||
|
typedef ttmath::Big<1, 8> MyBig;
|
||||||
|
ttmath::Parser<MyBig> parser;
|
||||||
|
parser.Parse("2^(2^63) + 1");
|
||||||
|
* fixed: similar problems were in methods Big::BitAnd() Big::BitOr() and Big::BitXor() (bitwise operations)
|
||||||
|
and they could return incorrect values
|
||||||
|
* fixed: in x86_64 asm code (*.asm for Win64) there was in some places esp register used,
|
||||||
|
there should be rsp used instead
|
||||||
|
this affects MS Windows users when they use the asm version (ttmathuint_x86_64_msvc.asm)
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.9.3 (2012.11.28):
|
||||||
|
* fixed: in Big::FromDouble(double value) (only 32 bit version)
|
||||||
|
buffer overflow in referencing to UInt<2>
|
||||||
|
this was used when 'value' was in so called "unnormalized" state
|
||||||
|
(E=0 and F is nonzero)
|
||||||
|
it produced incorrect mantissa (on about 8th decimal digit up)
|
||||||
|
* added: Parser::InitCGamma()
|
||||||
|
initializing coefficients used when calculating the gamma (or factorial) function
|
||||||
|
this speed up the next calculations
|
||||||
|
you don't have to call this method explicitly
|
||||||
|
these coefficients will be calculated when needed
|
||||||
|
* added: option 'group_digits' to Conv struct
|
||||||
|
you can set how many digits should be grouped
|
||||||
|
* changed: small optimizations in UInt::ToString() and Big::FromString()
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.9.2 (2010.09.23):
|
||||||
|
* 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)
|
||||||
|
* fixed: recurrence calling in Big::FromString(const std::string &, uint, const wchar_t **, bool *)
|
||||||
|
it should have the signature: Big::FromString(const std::string &, uint, const char **, bool *)
|
||||||
|
* fixed: Big::ToString method
|
||||||
|
in some cases when in the output string the exponent should be equal zero
|
||||||
|
the method changes the exponent to one so the last digit from the mantissa
|
||||||
|
was lost
|
||||||
|
* fixed: Big::ToDouble(double &) set always +INF (infinity)
|
||||||
|
when the value was too large (even for negative values)
|
||||||
|
(it should set -INF in such a case)
|
||||||
|
* added: some missing operators
|
||||||
|
UInt::operator~() /* bitwise neg */
|
||||||
|
UInt::operator&() /* bitwise and */
|
||||||
|
UInt::operator&=()
|
||||||
|
UInt::operator|() /* bitwise or */
|
||||||
|
UInt::operator|=()
|
||||||
|
UInt::operator^() /* bitwise xor */
|
||||||
|
UInt::operator^=()
|
||||||
|
Big::operator&()
|
||||||
|
Big::operator&=()
|
||||||
|
Big::operator|()
|
||||||
|
Big::operator|=()
|
||||||
|
Big::operator^()
|
||||||
|
Big::operator^=()
|
||||||
|
for Big<> we do not define bitwise neg
|
||||||
|
Big::operator++()
|
||||||
|
Big::operator++(int)
|
||||||
|
Big::operator--()
|
||||||
|
Big::operator--(int)
|
||||||
|
* added: macro TTMATH_DONT_USE_WCHAR
|
||||||
|
if defined then the library does not use wide characters
|
||||||
|
(wchar_t, std::wstring, ...) this is a workaround for some compilers
|
||||||
|
* added: bool UInt::IsOnlyTheHighestBitSet()
|
||||||
|
bool UInt::IsOnlyTheLowestBitSet()
|
||||||
|
returning true if only the highest/lowest bit is set
|
||||||
|
* added: uint Int::MulInt(sint ss2)
|
||||||
|
* added: void UInt::Swap(UInt<value_size> & ss2)
|
||||||
|
void Big::Swap(UInt<value_size> & ss2)
|
||||||
|
method for swapping this for an argument
|
||||||
|
* added: macro TTMATH_BIG_DEFAULT_CLEAR
|
||||||
|
when defined the default constructor from Big<> clears its mantissa and exponent
|
||||||
|
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
|
||||||
|
* added: some missing methods for converting
|
||||||
|
for UInt<>, Int<> and Big<> classes:
|
||||||
|
uint ToUInt()
|
||||||
|
sint ToInt()
|
||||||
|
ToUInt(uint32_t &)
|
||||||
|
ToInt(uint32_t &)
|
||||||
|
ToInt(int32_t &)
|
||||||
|
ToUInt(uint64_t &)
|
||||||
|
ToInt(uint64_t &)
|
||||||
|
ToInt(int64_t &)
|
||||||
|
FromUInt(uint32_t &)
|
||||||
|
FromInt(uint32_t &)
|
||||||
|
FromInt(int32_t &)
|
||||||
|
FromUInt(uint64_t &)
|
||||||
|
FromInt(uint64_t &)
|
||||||
|
FromInt(int64_t &)
|
||||||
|
and appropriate constructors and operators
|
||||||
|
* added: double Big::ToDouble() /there was only Big::ToDouble(double &) /
|
||||||
|
uint Big::ToFloat(float &)
|
||||||
|
float Big::ToFloat()
|
||||||
|
* changed: now asm version is available only on x86 and amd64
|
||||||
|
(and only for GCC and MS VC compilers)
|
||||||
|
* removed: macro TTMATH_RELEASE (now the 'release' version is default)
|
||||||
|
for debug version define TTMATH_DEBUG macro
|
||||||
|
TTMATH_DEBUG is also automatically defined when DEBUG or _DEBUG is set
|
||||||
|
* removed: macro TTMATH_REFERENCE_ASSERT from all methods in public interface
|
||||||
|
|
||||||
|
|
||||||
Version 0.9.1 (2010.02.07):
|
Version 0.9.1 (2010.02.07):
|
||||||
* fixed: the parser didn't use characters for changing the base (# and &)
|
* fixed: the parser didn't use characters for changing the base (# and &)
|
||||||
those characters were skipped
|
those characters were skipped
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# CMake configuration for ttmath
|
||||||
|
cmake_minimum_required (VERSION 3.0)
|
||||||
|
project(ttmath)
|
||||||
|
enable_testing()
|
||||||
|
include_directories(${ttmath_SOURCE_DIR})
|
||||||
|
add_subdirectory(samples)
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2006-2010, Tomasz Sowa
|
Copyright (c) 2006-2017, 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
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
o = main.o
|
o = main.o
|
||||||
CC = g++
|
CC = clang++
|
||||||
CFLAGS = -s -O2 -DTTMATH_CONSTANTSGENERATOR
|
CFLAGS = -O2 -DTTMATH_CONSTANTSGENERATOR
|
||||||
name = gen
|
name = gen
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ name = gen
|
||||||
all: $(name)
|
all: $(name)
|
||||||
|
|
||||||
$(name): $(o)
|
$(name): $(o)
|
||||||
$(CC) -o $(name) $(CFLAGS) $(o)
|
$(CC) -o $(name) -s $(CFLAGS) $(o)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
2543
doxygen.cfg
2543
doxygen.cfg
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
a=""
|
||||||
|
b=""
|
||||||
|
c=""
|
||||||
|
p=""
|
||||||
|
d=""
|
||||||
|
doxygen=""
|
||||||
|
|
||||||
|
# reading until not empty
|
||||||
|
|
||||||
|
while [ -z $a ]
|
||||||
|
do
|
||||||
|
echo -n "Major: " ; read a
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $b ]
|
||||||
|
do
|
||||||
|
echo -n "Minor: " ; read b;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $c ]
|
||||||
|
do
|
||||||
|
echo -n "Revision: " ; read c;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $p ]
|
||||||
|
do
|
||||||
|
echo -n "Prerelease? (y/n): " ; read p;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $d ]
|
||||||
|
do
|
||||||
|
echo -n "Add date? (y/n): " ; read d;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $doxygen ]
|
||||||
|
do
|
||||||
|
echo -n "Clean make and add to the package doxygen doc? (y/n): " ; read doxygen;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
mkdir -p releases
|
||||||
|
package_dir_name="ttmath-$a.$b.$c"
|
||||||
|
datestr=""
|
||||||
|
|
||||||
|
|
||||||
|
if [ $p = "y" -o $p = "Y" ]
|
||||||
|
then
|
||||||
|
package_dir_name=${package_dir_name}.prerelease
|
||||||
|
fi
|
||||||
|
|
||||||
|
package_dir_name=${package_dir_name}-src
|
||||||
|
|
||||||
|
if [ $d = "y" -o $d = "Y" ]
|
||||||
|
then
|
||||||
|
datestr=`/bin/date "+%G.%m.%d"`;
|
||||||
|
package_dir_name=${package_dir_name}-$datestr
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dir="releases/"${package_dir_name}
|
||||||
|
package=${package_dir_name}.tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
if [ -d $dir ]
|
||||||
|
then
|
||||||
|
echo "Directory $dir exists! (exiting)";
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "releases/"${package} ] ; then
|
||||||
|
echo "File releases/${package} exists! (exiting)"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
mkdir $dir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ $doxygen = "y" -o $doxygen = "Y" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "creating doxygen doc"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
rm -rf doc/doxygen
|
||||||
|
doxygen doxygen.cfg
|
||||||
|
|
||||||
|
cp -r doc $dir/
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "make clean in samples"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
make -C samples clean
|
||||||
|
make -C constgen clean
|
||||||
|
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "making source package"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
mkdir $dir/ttmath
|
||||||
|
mkdir $dir/samples
|
||||||
|
mkdir $dir/res
|
||||||
|
|
||||||
|
cp ttmath/* $dir/ttmath/
|
||||||
|
|
||||||
|
cp samples/* $dir/samples/
|
||||||
|
# cmake is not ready yet (cmake will generate Makefile which overwrites our own one)
|
||||||
|
rm $dir/samples/CMakeLists.txt
|
||||||
|
|
||||||
|
cp COPYRIGHT $dir/
|
||||||
|
cp README $dir/
|
||||||
|
cp CHANGELOG $dir/
|
||||||
|
|
||||||
|
cp res/ttmath_logo.svg $dir/res/
|
||||||
|
|
||||||
|
cd releases
|
||||||
|
tar -czf $package ${package_dir_name}
|
||||||
|
|
||||||
|
echo "the package has been created to:" releases/${package}
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="38.084499"
|
||||||
|
height="38.083"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="ttmath_logo.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.2"
|
||||||
|
inkscape:cx="24.511255"
|
||||||
|
inkscape:cy="17.621314"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="830"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-350.08291,-424.26987)">
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 369.125,424.28125 c -10.50699,0 -19.03125,8.52426 -19.03125,19.03125 0,10.50603 8.52426,19.03125 19.03125,19.03125 10.50746,0 19.03125,-8.52522 19.03125,-19.03125 0,-10.50699 -8.52379,-19.03125 -19.03125,-19.03125 z"
|
||||||
|
id="path3773" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffaa35;fill-opacity:1;stroke:none;stroke-width:1.62500000000000000;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 369.125,425.90625 c 9.62928,0 17.40625,7.77748 17.40625,17.40625 0,9.62773 -7.77697,17.40625 -17.40625,17.40625 -9.62877,0 -17.40625,-7.77852 -17.40625,-17.40625 0,-9.62877 7.77748,-17.40625 17.40625,-17.40625 z"
|
||||||
|
id="path2999-2" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 368.1875,432.65625 -0.1875,0.5 -6.34375,16.71875 -1.40625,-4 -0.5,-1.40625 -0.84375,1.25 -2.0625,3.125 1.25,0.8125 1.25,-1.875 1.5625,4.53125 0.6875,1.9375 0.71875,-1.9375 6.90625,-18.15625 8.65625,0 0,-1.5 -9.15625,0 -0.53125,0 z"
|
||||||
|
id="path3003-3"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 359.84375,434.34375 0,3 -3,0 0,1.5 3,0 0,3.21875 1.5,0 0,-3.21875 3,0 0,-1.5 -3,0 0,-3 -1.5,0 z"
|
||||||
|
id="path3005-3"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 371.0625,443.5625 0,0.46875 -0.125,4.6875 0,0.15625 0.125,0.15625 c 0,0 0.37411,0.46147 0.9375,0.9375 0.2817,0.23802 0.59509,0.49145 0.96875,0.6875 0.37366,0.19605 0.8013,0.32003 1.25,0.34375 0.93515,0.0491 1.77613,-0.36791 2.40625,-0.78125 0.63012,-0.41334 1.0625,-0.84375 1.0625,-0.84375 l 0.125,-0.15625 0,-0.1875 -0.0937,-5 0,-0.46875 -0.46875,0 -5.71875,0 -0.46875,0 z"
|
||||||
|
id="path3009-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccsscsccccccccc" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 377.65625,450.375 -0.0312,0.0312 -0.21875,0.125 c -2.30252,1.65271 -4.15395,1.52806 -6.1125,-0.1562 -1.78014,2.66032 -3.73192,7.25254 -4.29375,8.18745 -0.56183,0.93491 -0.17739,2.37424 -0.28125,3.375 l 0.5625,-0.0312 8.03125,-0.71875 0.125,-0.0312 0.0937,-0.0625 6.96875,-4.5625 0.1875,-0.125 0.0937,-0.0625 -0.0625,-0.3125 c 0.0108,-0.11043 0.0366,-0.43638 0,-0.96875 -0.0466,-1.03041 -0.48309,-1.60724 -0.93745,-2.24995 -0.5467,-0.58055 -1.33798,-1.08483 -2.15625,-1.5 -0.91162,-0.46254 -1.66155,-0.7891 -1.71875,-0.8125 l -0.0625,-0.0312 -0.1875,-0.0937 z"
|
||||||
|
id="path3013-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccczcccccccccccscccc" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 374.0625,438.21875 c -1.68685,0.1362 -5.3125,0.8125 -5.3125,0.8125 l -0.125,0.0312 -0.0625,0.125 -1.375,2.09375 -0.0312,0.0625 0,0.0937 0.1875,6.15625 0.0312,0.15625 0.125,0.0937 0.3125,0.21875 0.5,0.3125 -0.0312,-0.59375 -0.0937,-5.90625 c 0.081,-0.0694 0.35604,-0.32331 0.6875,-0.4375 l 0.0312,0 c 0.0323,-0.01 0.0883,0.01 0.125,0 l 1.46875,-0.0937 c 0.1093,0.60186 0.39332,1.20774 0.4812,1.8125 1.27397,-0.0782 2.40491,-0.17552 3.5031,-0.16892 1.08715,0.0103 2.17115,0.13001 3.2344,0.12517 l 0.0312,-0.6125 c 0,0 0.0422,-0.16533 0.0625,-0.28125 l 0.40625,-0.9375 c 0.004,-0.005 -0.004,-0.0267 0,-0.0312 l 0.0312,0 c 0.17093,-0.1709 0.53319,-0.25585 0.8125,-0.375 0.26159,-0.11159 0.42068,-0.28594 0.75,-0.375 l 0.0312,0 0.125,-0.0312 2.28125,-0.1875 0.0312,0 0.28125,0 0,-0.0312 0,-0.28125 0,-0.71875 0,-0.25 -0.25,-0.0625 -3.75,-0.71875 c -0.0114,-10e-4 -0.02,0.001 -0.0312,0 -1.37083,-0.13192 -2.78705,-0.1247 -4.40625,0 l -0.0312,0 -0.0312,0 z"
|
||||||
|
id="path3017-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccccccccccccccccccccsccccccccccccccccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,16 @@
|
||||||
|
# CMake configuration for ttmath/samples
|
||||||
|
|
||||||
|
# Building with Visual C++ x86_64 needs to compile the asm utilities first
|
||||||
|
if (MSVC AND "x${CMAKE_VS_PLATFORM_NAME}" STREQUAL "xx64")
|
||||||
|
set(TTMATH_MSVC64_ASM ttmathuint_x86_64_msvc.asm)
|
||||||
|
enable_language(ASM_MASM)
|
||||||
|
message(STATUS "Enabled MASM to compile '${TTMATH_MSVC64_ASM}'")
|
||||||
|
set(TTMATH_SRC_ASM ${ttmath_SOURCE_DIR}/ttmath/${TTMATH_MSVC64_ASM})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(SAMPLES big big2 int uint parser)
|
||||||
|
foreach(sample ${SAMPLES})
|
||||||
|
add_executable(${sample} ${sample}.cpp ${TTMATH_SRC_ASM})
|
||||||
|
# Allow to run all utilities at once as a test
|
||||||
|
add_test(${sample} ${sample})
|
||||||
|
endforeach()
|
|
@ -1,5 +1,6 @@
|
||||||
CC = g++
|
CC = g++
|
||||||
CFLAGS = -Wall -pedantic -s -O2 -I..
|
#CC = clang++
|
||||||
|
CFLAGS = -Wall -pedantic -O2 -I.. -DTTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
.SUFFIXES: .cpp .o
|
.SUFFIXES: .cpp .o
|
||||||
|
@ -12,19 +13,19 @@ all: uint int big big2 parser
|
||||||
|
|
||||||
|
|
||||||
uint: uint.o
|
uint: uint.o
|
||||||
$(CC) -o uint $(CFLAGS) uint.o
|
$(CC) -o uint -s $(CFLAGS) uint.o
|
||||||
|
|
||||||
int: int.o
|
int: int.o
|
||||||
$(CC) -o int $(CFLAGS) int.o
|
$(CC) -o int -s $(CFLAGS) int.o
|
||||||
|
|
||||||
big: big.o
|
big: big.o
|
||||||
$(CC) -o big $(CFLAGS) big.o
|
$(CC) -o big -s $(CFLAGS) big.o
|
||||||
|
|
||||||
big2: big2.o
|
big2: big2.o
|
||||||
$(CC) -o big2 $(CFLAGS) big2.o
|
$(CC) -o big2 -s $(CFLAGS) big2.o
|
||||||
|
|
||||||
parser: parser.o
|
parser: parser.o
|
||||||
$(CC) -o parser $(CFLAGS) parser.o
|
$(CC) -o parser -s $(CFLAGS) parser.o
|
||||||
|
|
||||||
|
|
||||||
uint.o: uint.cpp
|
uint.o: uint.cpp
|
||||||
|
@ -42,5 +43,5 @@ clean:
|
||||||
rm -f big
|
rm -f big
|
||||||
rm -f big2
|
rm -f big2
|
||||||
rm -f parser
|
rm -f parser
|
||||||
# on MS Windows can automatically be added suffixes .exe to the names of output programs
|
# on MS Windows suffixes .exe will be automatically added
|
||||||
rm -f *.exe
|
rm -f *.exe
|
||||||
|
|
|
@ -88,13 +88,13 @@ a = 123456.543456
|
||||||
b = 98767878.124322
|
b = 98767878.124322
|
||||||
a + b = 98891334.667778
|
a + b = 98891334.667778
|
||||||
a - b = -98644421.580866
|
a - b = -98644421.580866
|
||||||
a * b = 12193540837712.2708
|
a * b = 12193540837712.27076
|
||||||
a / b = 0.00124996654580957646
|
a / b = 0.00124996654580957646
|
||||||
Calculating with a carry
|
Calculating with a carry
|
||||||
a = 1.624801256066640878e+646457012
|
a = 1.6248012560666408782e+646457012
|
||||||
b = 456.319999999999993
|
b = 456.319999999999993
|
||||||
a + b = 1.624801256066640878e+646457012
|
a + b = 1.6248012560666408782e+646457012
|
||||||
a - b = 1.624801256066640878e+646457012
|
a - b = 1.6248012560666408782e+646457012
|
||||||
a * b = (carry)
|
a * b = (carry)
|
||||||
a / b = 3.560661939136222174e+646457009
|
a / b = 3.560661939136222174e+646457009
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -102,12 +102,12 @@ b = 98767878.124322
|
||||||
a + b = 98891334.667778
|
a + b = 98891334.667778
|
||||||
a - b = -98644421.580866
|
a - b = -98644421.580866
|
||||||
a * b = 12193540837712.270763536832
|
a * b = 12193540837712.270763536832
|
||||||
a / b = 0.001249966545809576460596448526166860913
|
a / b = 0.0012499665458095764605964485261668609133
|
||||||
Calculating with a carry
|
Calculating with a carry
|
||||||
a = 2.3495345545711177736883282090959505003e+2776511644261678604
|
a = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
b = 456.3199999999999931787897367030382156
|
b = 456.3199999999999931787897367030382156
|
||||||
a + b = 2.3495345545711177736883282090959505003e+2776511644261678604
|
a + b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
a - b = 2.3495345545711177736883282090959505003e+2776511644261678604
|
a - b = 2.34953455457111777368832820909595050034e+2776511644261678604
|
||||||
a * b = (carry)
|
a * b = (carry)
|
||||||
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
|
a / b = 5.1488748127873374141170361292780486452e+2776511644261678601
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,7 @@ const char equation[] = " (34 + 24) * 123 - 34.32 ^ 6 * sin(2.56) - atan(10)";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the result (on 32 bit platform):
|
the result (on 32 bit platform):
|
||||||
-897705014.52573107
|
-897705014.525731067
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CC = g++
|
CC = clang++
|
||||||
o = main.o uinttest.o
|
o = main.o uinttest.o
|
||||||
CFLAGS = -Wall -O2 -s
|
CFLAGS = -Wall -O2
|
||||||
ttmath = ..
|
ttmath = ..
|
||||||
name = tests
|
name = tests
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ all: $(name)
|
||||||
|
|
||||||
|
|
||||||
$(name): $(o)
|
$(name): $(o)
|
||||||
$(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o)
|
$(CC) -o $(name) -s $(CFLAGS) -I$(ttmath) $(o)
|
||||||
|
|
||||||
|
|
||||||
main.o: main.cpp uinttest.h
|
main.o: main.cpp uinttest.h
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
#CC = g++6
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||||
|
|
||||||
|
CC = clang++
|
||||||
|
CFLAGS = -Wall -pedantic -O3 -s -I..
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I..
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.SUFFIXES: .cpp .o
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
all: big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
big_64_64: main.cpp
|
||||||
|
$(CC) -o big_64_64 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=64 main.cpp
|
||||||
|
|
||||||
|
big_64_128: main.cpp
|
||||||
|
$(CC) -o big_64_128 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=128 main.cpp
|
||||||
|
|
||||||
|
big_64_192: main.cpp
|
||||||
|
$(CC) -o big_64_192 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=192 main.cpp
|
||||||
|
|
||||||
|
big_64_256: main.cpp
|
||||||
|
$(CC) -o big_64_256 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=256 main.cpp
|
||||||
|
|
||||||
|
big_64_512: main.cpp
|
||||||
|
$(CC) -o big_64_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||||
|
|
||||||
|
big_64_1024: main.cpp
|
||||||
|
$(CC) -o big_64_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||||
|
|
||||||
|
big_64_2048: main.cpp
|
||||||
|
$(CC) -o big_64_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||||
|
|
||||||
|
big_64_4096: main.cpp
|
||||||
|
$(CC) -o big_64_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||||
|
|
||||||
|
big_128_512: main.cpp
|
||||||
|
$(CC) -o big_128_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||||
|
|
||||||
|
big_256_1024: main.cpp
|
||||||
|
$(CC) -o big_256_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=256 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||||
|
|
||||||
|
big_512_2048: main.cpp
|
||||||
|
$(CC) -o big_512_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=512 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||||
|
|
||||||
|
big_128_4096: main.cpp
|
||||||
|
$(CC) -o big_128_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
test: all
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=64"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_64 "foo" | tee big_64_64.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=128"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_128 "foo" | tee big_64_128.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=192"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_192 "foo" | tee big_64_192.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=256"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_256 "foo" | tee big_64_256.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=512"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_512 "foo" | tee big_64_512.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=1024"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_1024 "foo" | tee big_64_1024.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=2048"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_2048 "foo" | tee big_64_2048.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=4096"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_4096 "foo" | tee big_64_4096.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=128 and mantissa=512"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_128_512 "foo" | tee big_128_512.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=128 and mantissa=4096"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_128_4096 "foo" | tee big_128_4096.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=256 and mantissa=1024"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_256_1024 "foo" | tee big_256_1024.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=512 and mantissa=2048"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_512_2048 "foo" | tee big_512_2048.out
|
||||||
|
|
||||||
|
./check_files.sh
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.out
|
||||||
|
rm -f big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||||
|
# on MS Windows suffixes .exe will be automatically added
|
||||||
|
rm -f *.exe
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
was_error=0
|
||||||
|
|
||||||
|
for expected in *.expected ; do
|
||||||
|
|
||||||
|
out=`basename $expected .expected`.out
|
||||||
|
|
||||||
|
if [ -f $out ] ; then
|
||||||
|
diff -u $out $expected
|
||||||
|
|
||||||
|
if [ `diff -u $out $expected | wc -l` -ne 0 ] ; then
|
||||||
|
was_error=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "there is no file: $out"
|
||||||
|
was_error=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
if [ $was_error -eq 0 ] ; then
|
||||||
|
echo "****************************************************************************"
|
||||||
|
echo " congratulations: all tests passed successfully"
|
||||||
|
echo "****************************************************************************"
|
||||||
|
else
|
||||||
|
echo "****************************************************************************"
|
||||||
|
echo " error: not all tests passed successfully"
|
||||||
|
echo "****************************************************************************"
|
||||||
|
fi
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include <ttmath/ttmath.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
typedef ttmath::Big<TTMATH_BITS(TTMATH_TEST_BIG_EXPONENT), TTMATH_BITS(TTMATH_TEST_BIG_MANTISSA)> MyBig;
|
||||||
|
ttmath::Parser<MyBig> parser;
|
||||||
|
std::string all_input;
|
||||||
|
|
||||||
|
for(int i=1 ; i<argc ; ++i)
|
||||||
|
{
|
||||||
|
if( i > 1 )
|
||||||
|
all_input += ' ';
|
||||||
|
|
||||||
|
all_input += argv[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << all_input << " = ";
|
||||||
|
ttmath::ErrorCode err = parser.Parse(all_input);
|
||||||
|
|
||||||
|
if( err == ttmath::err_ok )
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i < parser.stack.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( i > 0 )
|
||||||
|
std::cout << " ; ";
|
||||||
|
|
||||||
|
std::cout << parser.stack[i].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "error: " << static_cast<int>(err) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
206
ttmath/ttmath.h
206
ttmath/ttmath.h
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2017, 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
|
||||||
|
@ -79,10 +79,12 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this function skips the fraction from x
|
this function skips the fraction from x
|
||||||
e.g 2.2 = 2
|
|
||||||
2.7 = 2
|
samples
|
||||||
-2.2 = 2
|
- 2.2 = 2
|
||||||
-2.7 = 2
|
- 2.7 = 2
|
||||||
|
- -2.2 = 2
|
||||||
|
- -2.7 = 2
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType SkipFraction(const ValueType & x)
|
ValueType SkipFraction(const ValueType & x)
|
||||||
|
@ -96,10 +98,12 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this function rounds to the nearest integer value
|
this function rounds to the nearest integer value
|
||||||
e.g 2.2 = 2
|
|
||||||
2.7 = 3
|
samples
|
||||||
-2.2 = -2
|
- 2.2 = 2
|
||||||
-2.7 = -3
|
- 2.7 = 3
|
||||||
|
- -2.2 = -2
|
||||||
|
- -2.7 = -3
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Round(const ValueType & x, ErrorCode * err = 0)
|
ValueType Round(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
@ -127,12 +131,12 @@ namespace ttmath
|
||||||
this function returns a value representing the smallest integer
|
this function returns a value representing the smallest integer
|
||||||
that is greater than or equal to x
|
that is greater than or equal to x
|
||||||
|
|
||||||
Ceil(-3.7) = -3
|
- Ceil(-3.7) = -3
|
||||||
Ceil(-3.1) = -3
|
- Ceil(-3.1) = -3
|
||||||
Ceil(-3.0) = -3
|
- Ceil(-3.0) = -3
|
||||||
Ceil(4.0) = 4
|
- Ceil(4.0) = 4
|
||||||
Ceil(4.2) = 5
|
- Ceil(4.2) = 5
|
||||||
Ceil(4.8) = 5
|
- Ceil(4.8) = 5
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
|
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
@ -174,12 +178,12 @@ namespace ttmath
|
||||||
this function returns a value representing the largest integer
|
this function returns a value representing the largest integer
|
||||||
that is less than or equal to x
|
that is less than or equal to x
|
||||||
|
|
||||||
Floor(-3.6) = -4
|
- Floor(-3.6) = -4
|
||||||
Floor(-3.1) = -4
|
- Floor(-3.1) = -4
|
||||||
Floor(-3) = -3
|
- Floor(-3) = -3
|
||||||
Floor(2) = 2
|
- Floor(2) = 2
|
||||||
Floor(2.3) = 2
|
- Floor(2.3) = 2
|
||||||
Floor(2.8) = 2
|
- Floor(2.8) = 2
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
|
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
@ -273,12 +277,16 @@ namespace ttmath
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
|
ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
|
||||||
{
|
{
|
||||||
if( x.IsNan() || base.IsNan() )
|
if( x.IsNan() )
|
||||||
{
|
{
|
||||||
if( err )
|
if( err ) *err = err_improper_argument;
|
||||||
*err = err_improper_argument;
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
return ValueType(); // default NaN
|
if( base.IsNan() )
|
||||||
|
{
|
||||||
|
if( err ) *err = err_improper_argument;
|
||||||
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType result;
|
ValueType result;
|
||||||
|
@ -342,6 +350,9 @@ namespace ttmath
|
||||||
/*
|
/*
|
||||||
this namespace consists of auxiliary functions
|
this namespace consists of auxiliary functions
|
||||||
(something like 'private' in a class)
|
(something like 'private' in a class)
|
||||||
|
|
||||||
|
this is excluded from doxygen documentation
|
||||||
|
(option EXCLUDE_SYMBOLS in doxygen.cfg)
|
||||||
*/
|
*/
|
||||||
namespace auxiliaryfunctions
|
namespace auxiliaryfunctions
|
||||||
{
|
{
|
||||||
|
@ -523,7 +534,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( err )
|
if( err )
|
||||||
|
@ -854,7 +865,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( x.GreaterWithoutSignThan(one) )
|
if( x.GreaterWithoutSignThan(one) )
|
||||||
|
@ -862,7 +873,8 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
result.SetZeroNan();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( x.IsSign() )
|
if( x.IsSign() )
|
||||||
|
@ -1080,7 +1092,7 @@ namespace ttmath
|
||||||
bool change_sign = false;
|
bool change_sign = false;
|
||||||
|
|
||||||
if( x.IsNan() )
|
if( x.IsNan() )
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
|
|
||||||
// if x is negative we're using the formula:
|
// if x is negative we're using the formula:
|
||||||
// atan(-x) = -atan(x)
|
// atan(-x) = -atan(x)
|
||||||
|
@ -1548,7 +1560,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
@ -1584,7 +1596,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 180;
|
result = 180;
|
||||||
|
@ -1607,15 +1619,16 @@ namespace ttmath
|
||||||
minutes and seconds must be greater than or equal zero
|
minutes and seconds must be greater than or equal zero
|
||||||
|
|
||||||
result:
|
result:
|
||||||
if d>=0 : result= d + ((s/60)+m)/60
|
- if d>=0 : result= d + ((s/60)+m)/60
|
||||||
if d<0 : result= d - ((s/60)+m)/60
|
- if d<0 : result= d - ((s/60)+m)/60
|
||||||
|
|
||||||
((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because
|
((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because
|
||||||
there's only one division)
|
there's only one division)
|
||||||
|
|
||||||
for example:
|
samples:
|
||||||
DegToDeg(10, 30, 0) = 10.5
|
|
||||||
DegToDeg(10, 24, 35.6)=10.4098(8)
|
- DegToDeg(10, 30, 0) = 10.5
|
||||||
|
- DegToDeg(10, 24, 35.6)=10.4098(8)
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s,
|
ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s,
|
||||||
|
@ -1629,7 +1642,9 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return delimiter ; // NaN is set by default
|
delimiter.SetZeroNan(); // not needed, only to get rid of GCC warning about an uninitialized variable
|
||||||
|
|
||||||
|
return delimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
multipler = 60;
|
multipler = 60;
|
||||||
|
@ -1683,7 +1698,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
@ -1719,7 +1734,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 200;
|
result = 200;
|
||||||
|
@ -1751,7 +1766,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
@ -1801,7 +1816,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = x;
|
result = x;
|
||||||
|
@ -1842,7 +1857,9 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
x.SetNan();
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint c = x.Sqrt();
|
uint c = x.Sqrt();
|
||||||
|
@ -2042,18 +2059,19 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
indexth Root of x
|
caltulate the index'th Root of x
|
||||||
|
|
||||||
index must be integer and not negative <0;1;2;3....)
|
index must be integer and not negative <0;1;2;3....)
|
||||||
|
|
||||||
if index==0 the result is one
|
- if index==0 the result is one
|
||||||
if x==0 the result is zero and we assume root(0;0) is not defined
|
- if x==0 the result is zero and we assume root(0;0) is not defined
|
||||||
|
|
||||||
if index is even (2;4;6...) the result is x^(1/index) and x>0
|
- if index is even (2;4;6...) the result is x^(1/index) and x>0
|
||||||
if index is odd (1;2;3;...) the result is either
|
- if index is odd (1;2;3;...) the result is either
|
||||||
-(abs(x)^(1/index)) if x<0 or
|
- -(abs(x)^(1/index)) if x<0, or
|
||||||
x^(1/index)) if x>0
|
- x^(1/index)) if x>0
|
||||||
|
|
||||||
(for index==1 the result is equal x)
|
- for index==1 the result is equal x
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
|
ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
|
||||||
|
@ -2065,7 +2083,9 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
x.SetNan();
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( RootCheckIndexSign(x, index, err) ) return x;
|
if( RootCheckIndexSign(x, index, err) ) return x;
|
||||||
|
@ -2109,8 +2129,10 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
absolute value of x
|
absolute value of x
|
||||||
e.g. -2 = 2
|
|
||||||
2 = 2
|
samples:
|
||||||
|
- -2 = 2
|
||||||
|
- 2 = 2
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Abs(const ValueType & x)
|
ValueType Abs(const ValueType & x)
|
||||||
|
@ -2124,9 +2146,11 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
it returns the sign of the value
|
it returns the sign of the value
|
||||||
e.g. -2 = -1
|
|
||||||
0 = 0
|
samples:
|
||||||
10 = 1
|
- -2 = -1
|
||||||
|
- 0 = 0
|
||||||
|
- 10 = 1
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Sgn(ValueType x)
|
ValueType Sgn(ValueType x)
|
||||||
|
@ -2140,11 +2164,11 @@ namespace ttmath
|
||||||
/*!
|
/*!
|
||||||
the remainder from a division
|
the remainder from a division
|
||||||
|
|
||||||
e.g.
|
samples:
|
||||||
mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6
|
- mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6
|
||||||
mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-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
|
||||||
mod(-12.6 ; -3) = -0.6
|
- mod(-12.6 ; -3) = -0.6
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
|
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
|
||||||
|
@ -2154,7 +2178,9 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return ValueType(); // NaN is set by default
|
a.SetNan();
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint c = a.Mod(b);
|
uint c = a.Mod(b);
|
||||||
|
@ -2174,7 +2200,8 @@ namespace ttmath
|
||||||
this function is used to store factorials in a given container
|
this function is used to store factorials in a given container
|
||||||
'more' means how many values should be added at the end
|
'more' means how many values should be added at the end
|
||||||
|
|
||||||
e.g.
|
sample:
|
||||||
|
|
||||||
std::vector<ValueType> fact;
|
std::vector<ValueType> fact;
|
||||||
SetFactorialSequence(fact, 3);
|
SetFactorialSequence(fact, 3);
|
||||||
// now the container has three values: 1 1 2
|
// now the container has three values: 1 1 2
|
||||||
|
@ -2209,7 +2236,8 @@ namespace ttmath
|
||||||
an auxiliary function used to calculate Bernoulli numbers
|
an auxiliary function used to calculate Bernoulli numbers
|
||||||
|
|
||||||
this function returns a sum:
|
this function returns a sum:
|
||||||
sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)} k in [0, m-1] (m k) means binomial coefficient = (m! / (k! * (m-k)!))
|
|
||||||
|
sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)} k in [0, m-1] (m k) means binomial coefficient = (m! / (k! * (m-k)!))
|
||||||
|
|
||||||
you should have sufficient factorials in cgamma.fact
|
you should have sufficient factorials in cgamma.fact
|
||||||
(cgamma.fact should have at least m items)
|
(cgamma.fact should have at least m items)
|
||||||
|
@ -2264,8 +2292,9 @@ namespace ttmath
|
||||||
start is >= 2
|
start is >= 2
|
||||||
|
|
||||||
we use the recurrence formula:
|
we use the recurrence formula:
|
||||||
B(m) = 1 / (2*(1 - 2^m)) * sum(m)
|
|
||||||
where sum(m) is calculated by SetBernoulliNumbersSum()
|
B(m) = 1 / (2*(1 - 2^m)) * sum(m)
|
||||||
|
where sum(m) is calculated by SetBernoulliNumbersSum()
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
bool SetBernoulliNumbersMore(CGamma<ValueType> & cgamma, uint start, const volatile StopCalculating * stop = 0)
|
bool SetBernoulliNumbersMore(CGamma<ValueType> & cgamma, uint start, const volatile StopCalculating * stop = 0)
|
||||||
|
@ -2318,7 +2347,8 @@ namespace ttmath
|
||||||
returns false if there was a stop signal,
|
returns false if there was a stop signal,
|
||||||
'more' means how many values should be added at the end
|
'more' means how many values should be added at the end
|
||||||
|
|
||||||
e.g.
|
sample:
|
||||||
|
|
||||||
typedef Big<1,2> MyBig;
|
typedef Big<1,2> MyBig;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
SetBernoulliNumbers(cgamma, 3);
|
SetBernoulliNumbers(cgamma, 3);
|
||||||
|
@ -2365,9 +2395,11 @@ namespace ttmath
|
||||||
an auxiliary function used to calculate the Gamma() function
|
an auxiliary function used to calculate the Gamma() function
|
||||||
|
|
||||||
we calculate a sum:
|
we calculate a sum:
|
||||||
|
|
||||||
sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) ) } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ...
|
sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) ) } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ...
|
||||||
B(m) means a mth Bernoulli number
|
|
||||||
the sum starts from m=2, we calculate as long as the value will not change after adding a next part
|
B(m) means a mth Bernoulli number
|
||||||
|
the sum starts from m=2, we calculate as long as the value will not change after adding a next part
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
||||||
|
@ -2428,9 +2460,11 @@ namespace ttmath
|
||||||
an auxiliary function used to calculate the Gamma() function
|
an auxiliary function used to calculate the Gamma() function
|
||||||
|
|
||||||
we calculate a helper function GammaFactorialHigh() by using Stirling's series:
|
we calculate a helper function GammaFactorialHigh() by using Stirling's series:
|
||||||
n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) )
|
|
||||||
where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY)
|
n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) )
|
||||||
and sum(n) is calculated by GammaFactorialHighSum()
|
|
||||||
|
where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY)
|
||||||
|
and sum(n) is calculated by GammaFactorialHighSum()
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
||||||
|
@ -2482,7 +2516,8 @@ namespace ttmath
|
||||||
|
|
||||||
we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
|
we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
|
||||||
we use the formula:
|
we use the formula:
|
||||||
gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1)
|
|
||||||
|
gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1)
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & cgamma)
|
ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & cgamma)
|
||||||
|
@ -2533,11 +2568,12 @@ namespace ttmath
|
||||||
|
|
||||||
we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
|
we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
|
||||||
we use a recurrence formula:
|
we use a recurrence formula:
|
||||||
|
|
||||||
gamma(z+1) = z * gamma(z)
|
gamma(z+1) = z * gamma(z)
|
||||||
then: gamma(z) = gamma(z+1) / z
|
then: gamma(z) = gamma(z+1) / z
|
||||||
|
|
||||||
e.g.
|
samples:
|
||||||
gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
|
- gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
|
ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
|
||||||
|
@ -2628,11 +2664,13 @@ namespace ttmath
|
||||||
|
|
||||||
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma()
|
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma()
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
typedef Big<1,2> MyBig;
|
typedef Big<1,2> MyBig;
|
||||||
MyBig x=234, y=345.53;
|
MyBig x=234, y=345.53;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
std::cout << Gamma(x, cgamma) << std::endl;
|
std::cout << Gamma(x, cgamma) << std::endl;
|
||||||
std::cout << Gamma(y, cgamma) << std::endl;
|
std::cout << Gamma(y, cgamma) << std::endl;
|
||||||
|
|
||||||
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
||||||
and they will be reused in next calls to the function
|
and they will be reused in next calls to the function
|
||||||
|
|
||||||
|
@ -2652,7 +2690,7 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cgamma.history.Get(n, result, err_tmp) )
|
if( cgamma.history.Get(n, result, err_tmp) )
|
||||||
|
@ -2673,7 +2711,7 @@ namespace ttmath
|
||||||
if( n.IsZero() )
|
if( n.IsZero() )
|
||||||
{
|
{
|
||||||
err_tmp = err_improper_argument;
|
err_tmp = err_improper_argument;
|
||||||
result.SetNan();
|
result.SetZeroNan();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2731,7 +2769,9 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN set by default
|
x.SetNan();
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
|
@ -2754,11 +2794,13 @@ namespace ttmath
|
||||||
|
|
||||||
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial()
|
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial()
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
typedef Big<1,2> MyBig;
|
typedef Big<1,2> MyBig;
|
||||||
MyBig x=234, y=54345;
|
MyBig x=234, y=54345;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
std::cout << Factorial(x, cgamma) << std::endl;
|
std::cout << Factorial(x, cgamma) << std::endl;
|
||||||
std::cout << Factorial(y, cgamma) << std::endl;
|
std::cout << Factorial(y, cgamma) << std::endl;
|
||||||
|
|
||||||
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
||||||
and they will be reused in next calls to the function
|
and they will be reused in next calls to the function
|
||||||
|
|
||||||
|
@ -2818,10 +2860,14 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this is for convenience for the user
|
this is for convenience for the user
|
||||||
he can only use '#include <ttmath/ttmath.h>' even if he uses the parser
|
he can only use '#include <ttmath/ttmath.h>'
|
||||||
*/
|
*/
|
||||||
#include "ttmathparser.h"
|
#include "ttmathparser.h"
|
||||||
|
|
||||||
|
// Dec is not finished yet
|
||||||
|
//#include "ttmathdec.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
//warning C4127: conditional expression is constant
|
//warning C4127: conditional expression is constant
|
||||||
|
|
1885
ttmath/ttmathbig.h
1885
ttmath/ttmathbig.h
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,419 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of TTMath Bignum Library
|
||||||
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||||
|
* project may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfilettmathdec
|
||||||
|
#define headerfilettmathdec
|
||||||
|
|
||||||
|
#include "ttmathtypes.h"
|
||||||
|
#include "ttmaththreads.h"
|
||||||
|
#include "ttmathuint.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace ttmath
|
||||||
|
{
|
||||||
|
|
||||||
|
template<uint value_size, uint dec_digits>
|
||||||
|
class Dec
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
UInt<value_size> value;
|
||||||
|
unsigned char info;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sign
|
||||||
|
the mask of a bit from 'info' which means that there is a sign
|
||||||
|
(when the bit is set)
|
||||||
|
*/
|
||||||
|
#define TTMATH_DEC_SIGN 128
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Not a number
|
||||||
|
if this bit is set that there is not a valid number
|
||||||
|
*/
|
||||||
|
#define TTMATH_DEC_NAN 64
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dec()
|
||||||
|
{
|
||||||
|
info = TTMATH_DEC_NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Dec(const char * s)
|
||||||
|
{
|
||||||
|
info = TTMATH_DEC_NAN;
|
||||||
|
FromString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Dec<value_size, dec_digits> & operator=(const char * s)
|
||||||
|
{
|
||||||
|
FromString(s);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint FromString(const char * s, const char ** after_source = 0, bool * value_read = 0)
|
||||||
|
{
|
||||||
|
return FromStringBase(s, after_source, value_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ToString(std::string & result) const
|
||||||
|
{
|
||||||
|
ToStringBase(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method clears a specific bit in the 'info' variable
|
||||||
|
|
||||||
|
bit is one of:
|
||||||
|
*/
|
||||||
|
void ClearInfoBit(unsigned char bit)
|
||||||
|
{
|
||||||
|
info = info & (~bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets a specific bit in the 'info' variable
|
||||||
|
|
||||||
|
bit is one of:
|
||||||
|
|
||||||
|
*/
|
||||||
|
void SetInfoBit(unsigned char bit)
|
||||||
|
{
|
||||||
|
info = info | bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method returns true if a specific bit in the 'info' variable is set
|
||||||
|
|
||||||
|
bit is one of:
|
||||||
|
*/
|
||||||
|
bool IsInfoBit(unsigned char bit) const
|
||||||
|
{
|
||||||
|
return (info & bit) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsNan() const
|
||||||
|
{
|
||||||
|
return IsInfoBit(TTMATH_DEC_NAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsSign() const
|
||||||
|
{
|
||||||
|
return IsInfoBit(TTMATH_DEC_SIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method sets the sign
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
-1 -> -1
|
||||||
|
2 -> -2
|
||||||
|
|
||||||
|
we do not check whether there is a zero or not, if you're using this method
|
||||||
|
you must be sure that the value is (or will be afterwards) different from zero
|
||||||
|
*/
|
||||||
|
void SetSign()
|
||||||
|
{
|
||||||
|
SetInfoBit(TTMATH_DEC_SIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetNaN()
|
||||||
|
{
|
||||||
|
SetInfoBit(TTMATH_DEC_NAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Abs()
|
||||||
|
{
|
||||||
|
ClearInfoBit(TTMATH_DEC_SIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint Add(const Dec<value_size, dec_digits> & arg)
|
||||||
|
{
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
|
if( IsSign() == arg.IsSign() )
|
||||||
|
{
|
||||||
|
c += value.Add(arg.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool is_sign;
|
||||||
|
|
||||||
|
if( value > arg.value )
|
||||||
|
{
|
||||||
|
is_sign = IsSign();
|
||||||
|
value.Sub(arg.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_sign = arg.IsSign();
|
||||||
|
UInt<value_size> temp(this->value);
|
||||||
|
value = arg.value;
|
||||||
|
value.Sub(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_sign ? SetSign() : Abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
SetNaN();
|
||||||
|
|
||||||
|
return (c==0)? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint Sub(const Dec<value_size, dec_digits> & arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_MULTITHREADS
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
void SetMultipler(UInt<value_size> & result)
|
||||||
|
{
|
||||||
|
// this guardian is initialized before the program runs (static POD type)
|
||||||
|
static int guardian = 0;
|
||||||
|
static UInt<value_size> multipler;
|
||||||
|
|
||||||
|
if( guardian == 0 )
|
||||||
|
{
|
||||||
|
multipler = 10;
|
||||||
|
multipler.Pow(dec_digits);
|
||||||
|
guardian = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = multipler;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
void SetMultipler(UInt<value_size> & result)
|
||||||
|
{
|
||||||
|
// this guardian is initialized before the program runs (static POD type)
|
||||||
|
volatile static sig_atomic_t guardian = 0;
|
||||||
|
static UInt<value_size> * pmultipler;
|
||||||
|
|
||||||
|
// double-checked locking
|
||||||
|
if( guardian == 0 )
|
||||||
|
{
|
||||||
|
ThreadLock thread_lock;
|
||||||
|
|
||||||
|
// locking
|
||||||
|
if( thread_lock.Lock() )
|
||||||
|
{
|
||||||
|
static UInt<value_size> multipler;
|
||||||
|
|
||||||
|
if( guardian == 0 )
|
||||||
|
{
|
||||||
|
pmultipler = &multipler;
|
||||||
|
multipler = 10;
|
||||||
|
multipler.Pow(dec_digits);
|
||||||
|
guardian = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// there was a problem with locking, we store the result directly in 'result' object
|
||||||
|
result = 10;
|
||||||
|
result.Pow(dec_digits);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// automatically unlocking
|
||||||
|
}
|
||||||
|
|
||||||
|
result = *pmultipler;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary method for converting from a string
|
||||||
|
*/
|
||||||
|
template<class char_type>
|
||||||
|
uint FromStringBase(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
|
||||||
|
{
|
||||||
|
UInt<value_size> multipler;
|
||||||
|
const char_type * after;
|
||||||
|
uint c = 0;
|
||||||
|
info = 0;
|
||||||
|
|
||||||
|
Misc::SkipWhiteCharacters(s);
|
||||||
|
|
||||||
|
if( *s == '-' )
|
||||||
|
{
|
||||||
|
s += 1;
|
||||||
|
SetSign();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( *s == '+' )
|
||||||
|
{
|
||||||
|
s += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c += value.FromString(s, 10, &after, value_read);
|
||||||
|
|
||||||
|
if( after_source )
|
||||||
|
*after_source = after;
|
||||||
|
|
||||||
|
SetMultipler(multipler);
|
||||||
|
c += value.Mul(multipler);
|
||||||
|
|
||||||
|
if( *after == '.' )
|
||||||
|
c += FromStringBaseAfterComma(after+1, after_source);
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
SetInfoBit(TTMATH_DEC_NAN);
|
||||||
|
|
||||||
|
return (c==0)? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class char_type>
|
||||||
|
uint FromStringBaseAfterComma(const char_type * s, const char_type ** after_source = 0, bool * value_read = 0)
|
||||||
|
{
|
||||||
|
UInt<value_size> temp;
|
||||||
|
UInt<value_size> multipler;
|
||||||
|
sint z;
|
||||||
|
uint c = 0;
|
||||||
|
size_t i = dec_digits;
|
||||||
|
|
||||||
|
SetMultipler(multipler);
|
||||||
|
|
||||||
|
for( ; i>0 && (z=Misc::CharToDigit(*s, 10)) != -1 ; --i, ++s )
|
||||||
|
{
|
||||||
|
multipler.DivInt(10);
|
||||||
|
temp.SetZero();
|
||||||
|
|
||||||
|
if( value_read )
|
||||||
|
*value_read = true;
|
||||||
|
|
||||||
|
if( c == 0 )
|
||||||
|
{
|
||||||
|
temp.table[0] = z;
|
||||||
|
c += temp.Mul(multipler);
|
||||||
|
c += value.Add(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( i == 0 && (z=Misc::CharToDigit(*s, 10)) != -1 && z >= 5 )
|
||||||
|
c += value.AddOne();
|
||||||
|
|
||||||
|
if( after_source )
|
||||||
|
{
|
||||||
|
while( (z=Misc::CharToDigit(*s, 10)) != -1 )
|
||||||
|
s += 1;
|
||||||
|
|
||||||
|
*after_source = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class string_type>
|
||||||
|
void ToStringBase(string_type & result) const
|
||||||
|
{
|
||||||
|
if( IsNan() )
|
||||||
|
{
|
||||||
|
result = "NaN";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
value.ToStringBase(result, 10, IsSign());
|
||||||
|
|
||||||
|
if( dec_digits > 0 )
|
||||||
|
{
|
||||||
|
size_t size = result.size();
|
||||||
|
|
||||||
|
if( IsSign() && size > 0 )
|
||||||
|
size -= 1;
|
||||||
|
|
||||||
|
if( dec_digits >= size )
|
||||||
|
{
|
||||||
|
size_t zeroes = dec_digits - size + 1;
|
||||||
|
size_t start = IsSign() ? 1 : 0;
|
||||||
|
result.insert(start, zeroes, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
result.insert(result.end() - dec_digits, '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2017, 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
|
||||||
|
@ -55,8 +55,8 @@ namespace ttmath
|
||||||
\brief Int implements a big integer value with a sign
|
\brief Int implements a big integer value with a sign
|
||||||
|
|
||||||
value_size - how many bytes specify our value
|
value_size - how many bytes specify our value
|
||||||
on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
|
- on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
|
||||||
on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
|
- on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
|
||||||
value_size = 1,2,3,4,5,6....
|
value_size = 1,2,3,4,5,6....
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
|
@ -104,13 +104,10 @@ public:
|
||||||
*/
|
*/
|
||||||
uint ChangeSign()
|
uint ChangeSign()
|
||||||
{
|
{
|
||||||
Int<value_size> temp;
|
|
||||||
|
|
||||||
temp.SetMin();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if the value is equal that one which has been returned from SetMin
|
if the value is equal that one which has been returned from SetMin
|
||||||
that means we can't change sign because the value is too big (bigger about one)
|
(only the highest bit is set) that means we can't change sign
|
||||||
|
because the value is too big (bigger about one)
|
||||||
|
|
||||||
e.g. when value_size = 1 and value is -2147483648 we can't change it to the
|
e.g. when value_size = 1 and value is -2147483648 we can't change it to the
|
||||||
2147483648 because the max value which can be held is 2147483647
|
2147483648 because the max value which can be held is 2147483647
|
||||||
|
@ -119,13 +116,12 @@ public:
|
||||||
(if we look on our value without the sign we get the correct value
|
(if we look on our value without the sign we get the correct value
|
||||||
eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
|
eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
|
||||||
*/
|
*/
|
||||||
if( operator==(temp) )
|
if( UInt<value_size>::IsOnlyTheHighestBitSet() )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
temp.SetZero();
|
UInt<value_size> temp(*this);
|
||||||
temp.UInt<value_size>::Sub(*this);
|
UInt<value_size>::SetZero();
|
||||||
|
UInt<value_size>::Sub(temp);
|
||||||
operator=(temp);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -135,8 +131,9 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method sets the sign
|
this method sets the sign
|
||||||
|
|
||||||
e.g. 1 -> -1
|
samples
|
||||||
-2 -> -2
|
- 1 -> -1
|
||||||
|
- -2 -> -2
|
||||||
|
|
||||||
from a positive value we make a negative value,
|
from a positive value we make a negative value,
|
||||||
if the value is negative we do nothing
|
if the value is negative we do nothing
|
||||||
|
@ -294,10 +291,10 @@ public:
|
||||||
|
|
||||||
this = p1(=this) - p2
|
this = p1(=this) - p2
|
||||||
|
|
||||||
when p1>=0 i p2>=0 carry will never be set
|
- when p1>=0 i p2>=0 carry will never be set
|
||||||
when p1<0 i p2<0 carry will never be set
|
- when p1<0 i p2<0 carry will never be set
|
||||||
when p1>=0 i p2<0 carry is set when the highest bit of value is set
|
- when p1>=0 i p2<0 carry is set when the highest bit of value is set
|
||||||
when p1<0 i p2>=0 carry is set when the highest bit of value is clear
|
- when p1<0 i p2>=0 carry is set when the highest bit of value is clear
|
||||||
*/
|
*/
|
||||||
uint Sub(const Int<value_size> & ss2)
|
uint Sub(const Int<value_size> & ss2)
|
||||||
{
|
{
|
||||||
|
@ -350,33 +347,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
/*!
|
|
||||||
multiplication this = this * ss2
|
|
||||||
|
|
||||||
it returns carry if the result is too big
|
uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign)
|
||||||
(we're using the method from the base class but we have to make
|
|
||||||
one correction in account of signs)
|
|
||||||
*/
|
|
||||||
uint Mul(Int<value_size> ss2)
|
|
||||||
{
|
{
|
||||||
bool ss1_is_sign, ss2_is_sign;
|
|
||||||
|
|
||||||
ss1_is_sign = IsSign();
|
|
||||||
ss2_is_sign = ss2.IsSign();
|
|
||||||
|
|
||||||
/*
|
|
||||||
we don't have to check the carry from Abs (values will be correct
|
|
||||||
because next we're using the method Mul from the base class UInt
|
|
||||||
which is without a sign)
|
|
||||||
*/
|
|
||||||
Abs();
|
|
||||||
ss2.Abs();
|
|
||||||
|
|
||||||
if( UInt<value_size>::Mul(ss2) )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
we have to examine the sign of the result now
|
we have to examine the sign of the result now
|
||||||
but if the result is with the sign then:
|
but if the result is with the sign then:
|
||||||
|
@ -391,50 +366,114 @@ public:
|
||||||
*/
|
*/
|
||||||
if( IsSign() )
|
if( IsSign() )
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
there can be one case where signs are different and
|
|
||||||
the result will be equal the value from SetMin()
|
|
||||||
(this situation is ok)
|
|
||||||
*/
|
|
||||||
if( ss1_is_sign != ss2_is_sign )
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
{
|
{
|
||||||
Int<value_size> temp;
|
/*
|
||||||
temp.SetMin();
|
there can be one case where signs are different and
|
||||||
|
the result will be equal the value from SetMin() (only the highest bit is set)
|
||||||
if( operator!=(temp) )
|
(this situation is ok)
|
||||||
/*
|
*/
|
||||||
the result is too big
|
if( !UInt<value_size>::IsOnlyTheHighestBitSet() )
|
||||||
*/
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
// signs were the same
|
||||||
the result is too big
|
|
||||||
*/
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
multiplication: this = this * ss2
|
||||||
|
|
||||||
|
it can return a carry
|
||||||
|
*/
|
||||||
|
uint MulInt(sint ss2)
|
||||||
|
{
|
||||||
|
bool ss1_is_sign, ss2_is_sign;
|
||||||
|
uint c;
|
||||||
|
|
||||||
|
ss1_is_sign = IsSign();
|
||||||
|
|
||||||
|
/*
|
||||||
|
we don't have to check the carry from Abs (values will be correct
|
||||||
|
because next we're using the method MulInt from the base class UInt
|
||||||
|
which is without a sign)
|
||||||
|
*/
|
||||||
|
Abs();
|
||||||
|
|
||||||
|
if( ss2 < 0 )
|
||||||
|
{
|
||||||
|
ss2 = -ss2;
|
||||||
|
ss2_is_sign = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss2_is_sign = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = UInt<value_size>::MulInt((uint)ss2);
|
||||||
|
c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
|
||||||
|
|
||||||
if( ss1_is_sign != ss2_is_sign )
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
SetSign();
|
SetSign();
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
multiplication this = this * ss2
|
||||||
|
|
||||||
|
it returns carry if the result is too big
|
||||||
|
(we're using the method from the base class but we have to make
|
||||||
|
one correction in account of signs)
|
||||||
|
*/
|
||||||
|
uint Mul(Int<value_size> ss2)
|
||||||
|
{
|
||||||
|
bool ss1_is_sign, ss2_is_sign;
|
||||||
|
uint c;
|
||||||
|
|
||||||
|
ss1_is_sign = IsSign();
|
||||||
|
ss2_is_sign = ss2.IsSign();
|
||||||
|
|
||||||
|
/*
|
||||||
|
we don't have to check the carry from Abs (values will be correct
|
||||||
|
because next we're using the method Mul from the base class UInt
|
||||||
|
which is without a sign)
|
||||||
|
*/
|
||||||
|
Abs();
|
||||||
|
ss2.Abs();
|
||||||
|
|
||||||
|
c = UInt<value_size>::Mul(ss2);
|
||||||
|
c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
|
||||||
|
|
||||||
|
if( ss1_is_sign != ss2_is_sign )
|
||||||
|
SetSign();
|
||||||
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
division this = this / ss2
|
division this = this / ss2
|
||||||
returned values:
|
returned values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
|
|
||||||
for example: (result means 'this')
|
for example: (result means 'this')
|
||||||
20 / 3 --> result: 6 remainder: 2
|
- 20 / 3 --> result: 6 remainder: 2
|
||||||
-20 / 3 --> result: -6 remainder: -2
|
- -20 / 3 --> result: -6 remainder: -2
|
||||||
20 / -3 --> result: -6 remainder: 2
|
- 20 / -3 --> result: -6 remainder: 2
|
||||||
-20 / -3 --> result: 6 remainder: -2
|
- -20 / -3 --> result: 6 remainder: -2
|
||||||
|
|
||||||
in other words: this(old) = ss2 * this(new)(result) + remainder
|
in other words: this(old) = ss2 * this(new)(result) + remainder
|
||||||
*/
|
*/
|
||||||
|
@ -471,14 +510,14 @@ public:
|
||||||
/*!
|
/*!
|
||||||
division this = this / ss2 (ss2 is int)
|
division this = this / ss2 (ss2 is int)
|
||||||
returned values:
|
returned values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
|
|
||||||
for example: (result means 'this')
|
for example: (result means 'this')
|
||||||
20 / 3 --> result: 6 remainder: 2
|
- 20 / 3 --> result: 6 remainder: 2
|
||||||
-20 / 3 --> result: -6 remainder: -2
|
- -20 / 3 --> result: -6 remainder: -2
|
||||||
20 / -3 --> result: -6 remainder: 2
|
- 20 / -3 --> result: -6 remainder: 2
|
||||||
-20 / -3 --> result: 6 remainder: -2
|
- -20 / -3 --> result: 6 remainder: -2
|
||||||
|
|
||||||
in other words: this(old) = ss2 * this(new)(result) + remainder
|
in other words: this(old) = ss2 * this(new)(result) + remainder
|
||||||
*/
|
*/
|
||||||
|
@ -562,9 +601,9 @@ public:
|
||||||
power this = this ^ pow
|
power this = this ^ pow
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect arguments 0^0 or 0^(-something)
|
- 2 - incorrect arguments 0^0 or 0^(-something)
|
||||||
*/
|
*/
|
||||||
uint Pow(Int<value_size> pow)
|
uint Pow(Int<value_size> pow)
|
||||||
{
|
{
|
||||||
|
@ -688,6 +727,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts UInt<another_size> into this class
|
||||||
|
*/
|
||||||
|
template<uint argument_size>
|
||||||
|
uint FromInt(const UInt<argument_size> & p)
|
||||||
|
{
|
||||||
|
return FromUIntOrInt(p, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the uint type into this class
|
this method converts the uint type into this class
|
||||||
*/
|
*/
|
||||||
|
@ -707,6 +756,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the uint type into this class
|
||||||
|
*/
|
||||||
|
uint FromInt(uint value)
|
||||||
|
{
|
||||||
|
return FromUInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the default assignment operator
|
the default assignment operator
|
||||||
|
@ -756,7 +813,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
a copy constructor
|
a copy constructor
|
||||||
*/
|
*/
|
||||||
Int(const Int<value_size> & u)
|
Int(const Int<value_size> & u) : UInt<value_size>()
|
||||||
{
|
{
|
||||||
FromInt(u);
|
FromInt(u);
|
||||||
}
|
}
|
||||||
|
@ -820,63 +877,194 @@ 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)
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::FromUInt(n);
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if( value_size == 1 )
|
||||||
|
return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
|
||||||
|
|
||||||
|
if( value_size == 2 )
|
||||||
|
return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts unsigned 64 bit int type to this class
|
||||||
|
***this method is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
uint FromInt(ulint n)
|
||||||
|
{
|
||||||
|
return FromUInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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 unsigned 64 bit int type to this class
|
||||||
|
***this operator is created only on a 32bit platform***
|
||||||
|
*/
|
||||||
|
Int<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***
|
||||||
|
*/
|
||||||
|
Int(ulint n)
|
||||||
|
{
|
||||||
|
FromUInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the signed int type to this class
|
this method converts 32 bit unsigned int type to this class
|
||||||
|
|
||||||
***this operator is created only on a 64bit platform***
|
***this operator is created only on a 64bit platform***
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int<value_size> & operator=(signed int i)
|
uint FromUInt(unsigned int i)
|
||||||
{
|
{
|
||||||
FromInt(sint(i));
|
return FromUInt(uint(i));
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting the signed int to this class
|
this method converts 32 bit unsigned int type to this class
|
||||||
|
***this operator is created only on a 64bit platform***
|
||||||
***this constructor is created only on a 64bit platform***
|
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int(signed int i)
|
uint FromInt(unsigned int i)
|
||||||
{
|
{
|
||||||
FromInt(sint(i));
|
return FromUInt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the unsigned int type to this class
|
this method converts 32 bit signed int type to this class
|
||||||
|
***this operator is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
uint FromInt(signed int i)
|
||||||
|
{
|
||||||
|
return FromInt(sint(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts 32 bit unsigned int type to this class
|
||||||
***this operator is created only on a 64bit platform***
|
***this operator is created only on a 64bit platform***
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int<value_size> & operator=(unsigned int i)
|
Int<value_size> & operator=(unsigned int i)
|
||||||
{
|
{
|
||||||
FromUInt(uint(i));
|
FromUInt(i);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting the unsigned int to this class
|
a constructor for converting 32 bit unsigned int to this class
|
||||||
|
|
||||||
***this constructor is created only on a 64bit platform***
|
***this constructor is created only on a 64bit platform***
|
||||||
it takes one argument of 32bit
|
|
||||||
*/
|
*/
|
||||||
Int(unsigned int i)
|
Int(unsigned int i)
|
||||||
{
|
{
|
||||||
FromUInt(uint(i));
|
FromUInt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts 32 bit signed int type to this class
|
||||||
|
***this operator is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(signed int i)
|
||||||
|
{
|
||||||
|
FromInt(i);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for converting 32 bit signed int to this class
|
||||||
|
***this constructor is created only on a 64bit platform***
|
||||||
|
*/
|
||||||
|
Int(signed int i)
|
||||||
|
{
|
||||||
|
FromInt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting string to this class (with the base=10)
|
a constructor for converting string to this class (with the base=10)
|
||||||
*/
|
*/
|
||||||
|
@ -886,15 +1074,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
a constructor for converting string to this class (with the base=10)
|
|
||||||
*/
|
|
||||||
Int(const wchar_t * s)
|
|
||||||
{
|
|
||||||
FromString(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting a string to this class (with the base=10)
|
a constructor for converting a string to this class (with the base=10)
|
||||||
*/
|
*/
|
||||||
|
@ -904,6 +1083,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
a constructor for converting string to this class (with the base=10)
|
||||||
|
*/
|
||||||
|
Int(const wchar_t * s)
|
||||||
|
{
|
||||||
|
FromString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a constructor for converting a string to this class (with the base=10)
|
a constructor for converting a string to this class (with the base=10)
|
||||||
*/
|
*/
|
||||||
|
@ -912,6 +1102,8 @@ public:
|
||||||
FromString( s.c_str() );
|
FromString( s.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
a default constructor
|
a default constructor
|
||||||
|
@ -943,6 +1135,175 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to uint type
|
||||||
|
can return a carry if the value is too long to store it in uint type
|
||||||
|
*/
|
||||||
|
uint ToUInt(uint & result) const
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::ToUInt(result);
|
||||||
|
|
||||||
|
if( value_size == 1 )
|
||||||
|
return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to uint type
|
||||||
|
can return a carry if the value is too long to store it in uint type
|
||||||
|
*/
|
||||||
|
uint ToInt(uint & result) const
|
||||||
|
{
|
||||||
|
return ToUInt(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to sint type
|
||||||
|
can return a carry if the value is too long to store it in sint type
|
||||||
|
*/
|
||||||
|
uint ToInt(sint & result) const
|
||||||
|
{
|
||||||
|
result = sint( UInt<value_size>::table[0] );
|
||||||
|
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(uint i=1 ; i<value_size ; ++i)
|
||||||
|
if( UInt<value_size>::table[i] != mask )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to ulint type (64 bit unsigned integer)
|
||||||
|
can return a carry if the value is too long to store it in ulint type
|
||||||
|
*** this method is created only on a 32 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToUInt(ulint & result) const
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::ToUInt(result);
|
||||||
|
|
||||||
|
if( value_size == 1 )
|
||||||
|
return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
|
||||||
|
|
||||||
|
if( value_size == 2 )
|
||||||
|
return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to ulint type (64 bit unsigned integer)
|
||||||
|
can return a carry if the value is too long to store it in ulint type
|
||||||
|
*** this method is created only on a 32 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(ulint & result) const
|
||||||
|
{
|
||||||
|
return ToUInt(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to slint type (64 bit signed integer)
|
||||||
|
can return a carry if the value is too long to store it in slint type
|
||||||
|
*** this method is created only on a 32 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(slint & result) const
|
||||||
|
{
|
||||||
|
if( value_size == 1 )
|
||||||
|
{
|
||||||
|
result = slint(sint(UInt<value_size>::table[0]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint low = UInt<value_size>::table[0];
|
||||||
|
uint high = UInt<value_size>::table[1];
|
||||||
|
|
||||||
|
result = low;
|
||||||
|
result |= (ulint(high) << TTMATH_BITS_PER_UINT);
|
||||||
|
|
||||||
|
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(uint i=2 ; i<value_size ; ++i)
|
||||||
|
if( UInt<value_size>::table[i] != mask )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTMATH_PLATFORM64
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a 32 bit unsigned integer
|
||||||
|
can return a carry if the value is too long to store it in this type
|
||||||
|
*** this method is created only on a 64 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToUInt(unsigned int & result) const
|
||||||
|
{
|
||||||
|
uint c = UInt<value_size>::ToUInt(result);
|
||||||
|
|
||||||
|
if( c || IsSign() )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a 32 bit unsigned integer
|
||||||
|
can return a carry if the value is too long to store it in this type
|
||||||
|
*** this method is created only on a 64 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(unsigned int & result) const
|
||||||
|
{
|
||||||
|
return ToUInt(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a 32 bit signed integer
|
||||||
|
can return a carry if the value is too long to store it in this type
|
||||||
|
*** this method is created only on a 64 bit platform ***
|
||||||
|
*/
|
||||||
|
uint ToInt(int & result) const
|
||||||
|
{
|
||||||
|
uint first = UInt<value_size>::table[0];
|
||||||
|
|
||||||
|
result = int(first);
|
||||||
|
uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
|
||||||
|
|
||||||
|
if( (first >> 31) != (mask >> 31) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(uint i=1 ; i<value_size ; ++i)
|
||||||
|
if( UInt<value_size>::table[i] != mask )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -955,13 +1316,11 @@ private:
|
||||||
{
|
{
|
||||||
Int<value_size> temp(*this);
|
Int<value_size> temp(*this);
|
||||||
temp.Abs();
|
temp.Abs();
|
||||||
|
temp.UInt<value_size>::ToStringBase(result, b, true);
|
||||||
temp.UInt<value_size>::ToString(result, b);
|
|
||||||
result.insert(result.begin(), '-');
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt<value_size>::ToString(result, b);
|
UInt<value_size>::ToStringBase(result, b, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -976,15 +1335,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts the value to a string with a base equal 'b'
|
|
||||||
*/
|
|
||||||
void ToString(std::wstring & result, uint b = 10) const
|
|
||||||
{
|
|
||||||
return ToStringBase(result, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the value to a string with a base equal 'b'
|
this method converts the value to a string with a base equal 'b'
|
||||||
*/
|
*/
|
||||||
|
@ -997,6 +1347,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts the value to a string with a base equal 'b'
|
||||||
|
*/
|
||||||
|
void ToString(std::wstring & result, uint b = 10) const
|
||||||
|
{
|
||||||
|
return ToStringBase(result, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method converts the value to a string with a base equal 'b'
|
this method converts the value to a string with a base equal 'b'
|
||||||
*/
|
*/
|
||||||
|
@ -1008,6 +1369,9 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -1111,16 +1475,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this method converts a string into its value
|
|
||||||
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
|
||||||
*/
|
|
||||||
uint FromString(const std::wstring & s, uint b = 10)
|
|
||||||
{
|
|
||||||
return FromString( s.c_str(), b );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
|
@ -1132,6 +1486,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this method converts a string into its value
|
||||||
|
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
|
||||||
|
*/
|
||||||
|
uint FromString(const std::wstring & s, uint b = 10)
|
||||||
|
{
|
||||||
|
return FromString( s.c_str(), b );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
|
@ -1143,6 +1510,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
this operator converts a string into its value (with base = 10)
|
||||||
|
*/
|
||||||
|
Int<value_size> & operator=(const std::wstring & s)
|
||||||
|
{
|
||||||
|
FromString( s.c_str() );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this operator converts a string into its value (with base = 10)
|
this operator converts a string into its value (with base = 10)
|
||||||
*/
|
*/
|
||||||
|
@ -1154,16 +1534,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
this operator converts a string into its value (with base = 10)
|
|
||||||
*/
|
|
||||||
Int<value_size> & operator=(const std::wstring & s)
|
|
||||||
{
|
|
||||||
FromString( s.c_str() );
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
|
@ -1382,11 +1752,9 @@ public:
|
||||||
|
|
||||||
Int<value_size> & operator%=(const Int<value_size> & p2)
|
Int<value_size> & operator%=(const Int<value_size> & p2)
|
||||||
{
|
{
|
||||||
Int<value_size> temp(*this);
|
|
||||||
Int<value_size> remainder;
|
Int<value_size> remainder;
|
||||||
|
|
||||||
temp.Div(p2, remainder);
|
Div(p2, remainder);
|
||||||
|
|
||||||
operator=(remainder);
|
operator=(remainder);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -1472,6 +1840,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
output to standard streams
|
output to standard streams
|
||||||
*/
|
*/
|
||||||
|
@ -1480,6 +1850,8 @@ public:
|
||||||
return OutputToStream<std::wostream, std::wstring>(s, l);
|
return OutputToStream<std::wostream, std::wstring>(s, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1532,6 +1904,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
input from standard streams
|
input from standard streams
|
||||||
*/
|
*/
|
||||||
|
@ -1539,6 +1913,8 @@ public:
|
||||||
{
|
{
|
||||||
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
|
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
@ -75,6 +75,8 @@ static void AssignString(std::string & result, const char * str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
result = str
|
result = str
|
||||||
*/
|
*/
|
||||||
|
@ -116,6 +118,8 @@ static void AssignString(std::string & result, const std::wstring & str)
|
||||||
return AssignString(result, str.c_str());
|
return AssignString(result, str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -134,6 +138,8 @@ static void AddString(std::string & result, const char * str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
result += str
|
result += str
|
||||||
*/
|
*/
|
||||||
|
@ -143,6 +149,7 @@ static void AddString(std::wstring & result, const char * str)
|
||||||
result += *str;
|
result += *str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -164,10 +171,10 @@ static void SkipWhiteCharacters(const char_type * & c)
|
||||||
this static method converts one character into its value
|
this static method converts one character into its value
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
1 -> 1
|
- 1 -> 1
|
||||||
8 -> 8
|
- 8 -> 8
|
||||||
A -> 10
|
- A -> 10
|
||||||
f -> 15
|
- f -> 15
|
||||||
|
|
||||||
this method don't check whether c is correct or not
|
this method don't check whether c is correct or not
|
||||||
*/
|
*/
|
||||||
|
@ -188,9 +195,9 @@ return c-'A'+10;
|
||||||
(if there can't be a correct value it returns -1)
|
(if there can't be a correct value it returns -1)
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
c=2, base=10 -> function returns 2
|
- c=2, base=10 -> function returns 2
|
||||||
c=A, base=10 -> function returns -1
|
- c=A, base=10 -> function returns -1
|
||||||
c=A, base=16 -> function returns 10
|
- c=A, base=16 -> function returns 10
|
||||||
*/
|
*/
|
||||||
static sint CharToDigit(uint c, uint base)
|
static sint CharToDigit(uint c, uint base)
|
||||||
{
|
{
|
||||||
|
@ -221,10 +228,10 @@ return sint(c);
|
||||||
(we don't have to get a base)
|
(we don't have to get a base)
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
1 -> 1
|
- 1 -> 1
|
||||||
8 -> 8
|
- 8 -> 8
|
||||||
10 -> A
|
- 10 -> A
|
||||||
15 -> F
|
- 15 -> F
|
||||||
*/
|
*/
|
||||||
static uint DigitToChar(uint digit)
|
static uint DigitToChar(uint digit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Mathematical Library
|
* This file is a part of TTMath Mathematical Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
* Copyright (c) 2006-2017, 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
|
||||||
|
@ -81,7 +81,7 @@ public:
|
||||||
// (if there's a variable this 'param' is ignored)
|
// (if there's a variable this 'param' is ignored)
|
||||||
int param;
|
int param;
|
||||||
|
|
||||||
Item() {}
|
Item() { param = 0; }
|
||||||
Item(const std::string & v, int p) : value(v), param(p) {}
|
Item(const std::string & v, int p) : value(v), param(p) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ public:
|
||||||
if 'can_be_digit' is true that means when the 'c' is a digit this
|
if 'can_be_digit' is true that means when the 'c' is a digit this
|
||||||
method returns true otherwise it returns false
|
method returns true otherwise it returns false
|
||||||
*/
|
*/
|
||||||
static bool CorrectCharacter(wchar_t c, bool can_be_digit)
|
static bool CorrectCharacter(int c, bool can_be_digit)
|
||||||
{
|
{
|
||||||
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
|
||||||
return true;
|
return true;
|
||||||
|
@ -148,6 +148,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns true if such an object is defined (name exists)
|
this method returns true if such an object is defined (name exists)
|
||||||
*/
|
*/
|
||||||
|
@ -163,6 +166,8 @@ public:
|
||||||
return IsDefined(str_tmp1);
|
return IsDefined(str_tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds one object (variable of function) into the table
|
this method adds one object (variable of function) into the table
|
||||||
|
@ -184,6 +189,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method adds one object (variable of function) into the table
|
this method adds one object (variable of function) into the table
|
||||||
*/
|
*/
|
||||||
|
@ -200,6 +207,8 @@ public:
|
||||||
return Add(str_tmp1, str_tmp2, param);
|
return Add(str_tmp1, str_tmp2, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns 'true' if the table is empty
|
this method returns 'true' if the table is empty
|
||||||
|
@ -258,6 +267,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the value and the number of parameters for a specific object
|
this method changes the value and the number of parameters for a specific object
|
||||||
*/
|
*/
|
||||||
|
@ -274,6 +286,8 @@ public:
|
||||||
return EditValue(str_tmp1, str_tmp2, param);
|
return EditValue(str_tmp1, str_tmp2, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the name of a specific object
|
this method changes the name of a specific object
|
||||||
|
@ -306,6 +320,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method changes the name of a specific object
|
this method changes the name of a specific object
|
||||||
*/
|
*/
|
||||||
|
@ -322,6 +340,8 @@ public:
|
||||||
return EditName(str_tmp1, str_tmp2);
|
return EditName(str_tmp1, str_tmp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method deletes an object
|
this method deletes an object
|
||||||
|
@ -342,6 +362,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method deletes an object
|
this method deletes an object
|
||||||
*/
|
*/
|
||||||
|
@ -357,6 +380,8 @@ public:
|
||||||
return Delete(str_tmp1);
|
return Delete(str_tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
|
@ -380,6 +405,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
*/
|
*/
|
||||||
|
@ -397,6 +424,8 @@ public:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
|
@ -421,6 +450,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value of a specific object
|
this method gets the value of a specific object
|
||||||
(this version is used for not copying the whole string)
|
(this version is used for not copying the whole string)
|
||||||
|
@ -437,6 +468,8 @@ public:
|
||||||
return GetValue(str_tmp1, value);
|
return GetValue(str_tmp1, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value and the number of parameters
|
this method gets the value and the number of parameters
|
||||||
|
@ -451,7 +484,7 @@ public:
|
||||||
|
|
||||||
if( i == table.end() )
|
if( i == table.end() )
|
||||||
{
|
{
|
||||||
value.empty();
|
value.clear();
|
||||||
*param = 0;
|
*param = 0;
|
||||||
return err_unknown_object;
|
return err_unknown_object;
|
||||||
}
|
}
|
||||||
|
@ -463,6 +496,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method gets the value and the number of parameters
|
this method gets the value and the number of parameters
|
||||||
of a specific object
|
of a specific object
|
||||||
|
@ -481,6 +516,8 @@ public:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value and the number of parameters
|
this method sets the value and the number of parameters
|
||||||
|
@ -508,6 +545,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets the value and the number of parameters
|
this method sets the value and the number of parameters
|
||||||
of a specific object
|
of a specific object
|
||||||
|
@ -527,6 +567,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method returns a pointer into the table
|
this method returns a pointer into the table
|
||||||
*/
|
*/
|
||||||
|
@ -680,14 +723,17 @@ public:
|
||||||
|
|
||||||
in multithreaded environment you can provide an object of this class to
|
in multithreaded environment you can provide an object of this class to
|
||||||
the Gamma() or Factorial() function, e.g;
|
the Gamma() or Factorial() function, e.g;
|
||||||
|
|
||||||
typedef Big<1, 3> MyBig;
|
typedef Big<1, 3> MyBig;
|
||||||
MyBig x = 123456;
|
MyBig x = 123456;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
std::cout << Gamma(x, cgamma);
|
std::cout << Gamma(x, cgamma);
|
||||||
|
|
||||||
each thread should have its own CGamma<> object
|
each thread should have its own CGamma<> object
|
||||||
|
|
||||||
in a single-thread environment a CGamma<> object is a static variable
|
in a single-thread environment a CGamma<> object is a static variable
|
||||||
in a second version of Gamma() and you don't have to explicitly use it, e.g.
|
and you don't have to explicitly use it, e.g.
|
||||||
|
|
||||||
typedef Big<1, 3> MyBig;
|
typedef Big<1, 3> MyBig;
|
||||||
MyBig x = 123456;
|
MyBig x = 123456;
|
||||||
std::cout << Gamma(x);
|
std::cout << Gamma(x);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -59,24 +59,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
this is a simple skeleton of a program in multithreads environment:
|
|
||||||
|
|
||||||
#define TTMATH_MULTITHREADS
|
|
||||||
#include<ttmath/ttmath.h>
|
|
||||||
|
|
||||||
TTMATH_MULTITHREADS_HELPER
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
|
|
||||||
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
|
||||||
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -186,12 +168,32 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
objects of this class are used to synchronize
|
\brief objects of this class are used to synchronize
|
||||||
|
|
||||||
|
this is a simple skeleton of a program in multithreads environment:
|
||||||
|
|
||||||
|
#define TTMATH_MULTITHREADS
|
||||||
|
#include<ttmath/ttmath.h>
|
||||||
|
|
||||||
|
TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
|
||||||
|
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
||||||
|
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
||||||
*/
|
*/
|
||||||
class ThreadLock
|
class ThreadLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
lock the current thread
|
||||||
|
|
||||||
|
it uses a global mutex created by TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
*/
|
||||||
bool Lock()
|
bool Lock()
|
||||||
{
|
{
|
||||||
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
* Copyright (c) 2006-2019, 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
|
||||||
|
@ -56,70 +56,121 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/*!
|
#ifndef _MSC_VER
|
||||||
the version of the library
|
#include <stdint.h>
|
||||||
|
// for uint64_t and int64_t on a 32 bit platform
|
||||||
TTMATH_PRERELEASE_VER is either zero or one
|
|
||||||
if zero that means this is the release version of the library
|
|
||||||
*/
|
|
||||||
#define TTMATH_MAJOR_VER 0
|
|
||||||
#define TTMATH_MINOR_VER 9
|
|
||||||
#define TTMATH_REVISION_VER 1
|
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
TTMATH_DEBUG
|
|
||||||
this macro enables further testing during writing your code
|
|
||||||
you don't have to define it in a release mode
|
|
||||||
|
|
||||||
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
|
||||||
are set as well and these macros can throw an exception if a condition in it
|
|
||||||
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
|
||||||
|
|
||||||
TTMATH_RELEASE
|
|
||||||
if you are confident that your code is perfect you can define TTMATH_RELEASE
|
|
||||||
macro for example by using -D option in gcc
|
|
||||||
gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp
|
|
||||||
or by defining this macro in your code before using any header files of this library
|
|
||||||
|
|
||||||
if TTMATH_RELEASE is not set then TTMATH_DEBUG is set automatically
|
|
||||||
*/
|
|
||||||
#ifndef TTMATH_RELEASE
|
|
||||||
#define TTMATH_DEBUG
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the major version of the library
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||||
|
*/
|
||||||
|
#define TTMATH_MAJOR_VER 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the minor version of the library
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||||
|
*/
|
||||||
|
#define TTMATH_MINOR_VER 9
|
||||||
|
|
||||||
|
/*!
|
||||||
|
the revision version of the library
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if TTMATH_PRERELEASE_VER==1]
|
||||||
|
*/
|
||||||
|
#define TTMATH_REVISION_VER 4
|
||||||
|
|
||||||
|
/*!
|
||||||
|
TTMATH_PRERELEASE_VER is either zero or one
|
||||||
|
zero means that this is the release version of the library
|
||||||
|
(one means something like beta)
|
||||||
|
|
||||||
|
the version present to the end user is constructed in this way:
|
||||||
|
|
||||||
|
TTMATH_MAJOR_VER.TTMATH_MINOR_VER.TTMATH_REVISION_VER.[prerelease if 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 _M_X64 && !defined __x86_64__
|
||||||
|
|
||||||
|
/*
|
||||||
|
other platforms than x86 and amd64 are not recognized at the moment
|
||||||
|
so you should set TTMATH_PLATFORMxx manually
|
||||||
|
*/
|
||||||
|
|
||||||
|
// we're using a 32bit platform
|
||||||
|
#define TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// we're using a 64bit platform
|
||||||
|
#define TTMATH_PLATFORM64
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
#ifndef TTMATH_FORCEASM
|
||||||
|
|
||||||
|
#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, CLANG (LLVM) 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 or CLANG (LLVM) by default use no asm version
|
||||||
|
(CLANG defines __GNUC__ too)
|
||||||
|
*/
|
||||||
|
#define TTMATH_NOASM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
#if !defined _M_X64 && !defined __x86_64__
|
|
||||||
|
|
||||||
/*!
|
|
||||||
we're using a 32bit platform
|
|
||||||
*/
|
|
||||||
#define TTMATH_PLATFORM32
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*!
|
|
||||||
we're using a 64bit platform
|
|
||||||
*/
|
|
||||||
#define TTMATH_PLATFORM64
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
another compilers than MS VC or GCC by default use no asm version (TTMATH_NOASM)
|
|
||||||
*/
|
|
||||||
#if !defined _MSC_VER && !defined __GNUC__
|
|
||||||
#define TTMATH_NOASM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
@ -130,17 +181,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
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -175,26 +227,25 @@ namespace ttmath
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*!
|
|
||||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
|
||||||
*/
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
||||||
typedef unsigned __int64 uint;
|
typedef unsigned __int64 uint;
|
||||||
typedef signed __int64 sint;
|
typedef signed __int64 sint;
|
||||||
#else
|
#else
|
||||||
typedef unsigned long uint;
|
/*!
|
||||||
typedef signed long sint;
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
|
*/
|
||||||
|
typedef uint64_t uint;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
|
*/
|
||||||
|
typedef int64_t sint;
|
||||||
#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
|
||||||
|
@ -295,12 +346,12 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
lib type codes:
|
lib type codes:
|
||||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
asm_vc_64 - with asm for VC (64 bit)
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
asm_gcc_64 - with asm for GCC (64 bit)
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
*/
|
*/
|
||||||
enum LibTypeCode
|
enum LibTypeCode
|
||||||
{
|
{
|
||||||
|
@ -344,7 +395,8 @@ namespace ttmath
|
||||||
err_unknown_object,
|
err_unknown_object,
|
||||||
err_still_calculating,
|
err_still_calculating,
|
||||||
err_in_short_form_used_function,
|
err_in_short_form_used_function,
|
||||||
err_percent_from
|
err_percent_from,
|
||||||
|
err_assignment_requires_variable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,7 +423,7 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
used only in Big::ToString()
|
used only in Big::ToString()
|
||||||
if scient is false then the value will be print in the scientific mode
|
if scient is false then the value will be printed in the scientific mode
|
||||||
only if the exponent is greater than scien_from
|
only if the exponent is greater than scien_from
|
||||||
default: 15
|
default: 15
|
||||||
*/
|
*/
|
||||||
|
@ -385,10 +437,11 @@ namespace ttmath
|
||||||
default: true
|
default: true
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
Conv c;
|
|
||||||
c.base_round = false;
|
Conv c;
|
||||||
Big<1, 1> a = "0.1"; // decimal input
|
c.base_round = false;
|
||||||
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
|
Big<1, 1> a = "0.1"; // decimal input
|
||||||
|
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
|
||||||
*/
|
*/
|
||||||
bool base_round;
|
bool base_round;
|
||||||
|
|
||||||
|
@ -444,6 +497,13 @@ namespace ttmath
|
||||||
uint group;
|
uint group;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
how many digits should be grouped (it is used if 'group' is non zero)
|
||||||
|
default: 3
|
||||||
|
*/
|
||||||
|
uint group_digits;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*/
|
*/
|
||||||
uint group_exp; // not implemented yet
|
uint group_exp; // not implemented yet
|
||||||
|
@ -463,6 +523,7 @@ namespace ttmath
|
||||||
comma = '.';
|
comma = '.';
|
||||||
comma2 = ',';
|
comma2 = ',';
|
||||||
group = 0;
|
group = 0;
|
||||||
|
group_digits = 3;
|
||||||
group_exp = 0;
|
group_exp = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -521,26 +582,13 @@ namespace ttmath
|
||||||
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
In the library is used macro TTMATH_REFERENCE_ASSERT which
|
||||||
can throw an exception of this type
|
can throw an exception of this type
|
||||||
|
|
||||||
|
** from version 0.9.2 this macro is removed from all methods
|
||||||
|
in public interface so you don't have to worry about it **
|
||||||
|
|
||||||
If you compile with gcc you can get a small benefit
|
If you compile with gcc you can get a small benefit
|
||||||
from using method Where() (it returns std::string) with
|
from using method Where() (it returns std::string) with
|
||||||
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
|
||||||
was used)
|
was used)
|
||||||
|
|
||||||
What is the 'reference' error?
|
|
||||||
Some kind of methods use a reference as their argument to another object,
|
|
||||||
and the another object not always can be the same which is calling, e.g.
|
|
||||||
Big<1,2> foo(10);
|
|
||||||
foo.Mul(foo); // this is incorrect
|
|
||||||
above method Mul is making something more with 'this' object and
|
|
||||||
'this' cannot be passed as the argument because the result will be undefined
|
|
||||||
|
|
||||||
macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
|
|
||||||
|
|
||||||
note! some methods can use 'this' object as the argument
|
|
||||||
for example this code is correct:
|
|
||||||
UInt<2> foo(10);
|
|
||||||
foo.Add(foo);
|
|
||||||
but there are only few methods which can do that
|
|
||||||
*/
|
*/
|
||||||
class ReferenceError : public std::logic_error, public ExceptionInfo
|
class ReferenceError : public std::logic_error, public ExceptionInfo
|
||||||
{
|
{
|
||||||
|
@ -596,8 +644,21 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
|
TTMATH_DEBUG
|
||||||
|
this macro enables further testing during writing your code
|
||||||
|
you don't have to define it in a release mode
|
||||||
|
|
||||||
|
if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
|
||||||
|
are set as well and these macros can throw an exception if a condition in it
|
||||||
|
is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
|
||||||
|
|
||||||
|
TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
|
||||||
*/
|
*/
|
||||||
|
#if defined DEBUG || defined _DEBUG
|
||||||
|
#define TTMATH_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_DEBUG
|
#ifdef TTMATH_DEBUG
|
||||||
|
|
||||||
#if defined(__FILE__) && defined(__LINE__)
|
#if defined(__FILE__) && defined(__LINE__)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
@ -39,15 +39,16 @@
|
||||||
#define headerfilettmathuint_noasm
|
#define headerfilettmathuint_noasm
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_NOASM
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file ttmathuint_noasm.h
|
\file ttmathuint_noasm.h
|
||||||
\brief template class UInt<uint> with methods without any assembler code
|
\brief template class UInt<uint> with methods without any assembler code (used for no-asm version of ttmath)
|
||||||
|
|
||||||
this file is included at the end of ttmathuint.h
|
this file is included at the end of ttmathuint.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef TTMATH_NOASM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
@ -55,12 +56,12 @@ namespace ttmath
|
||||||
/*!
|
/*!
|
||||||
returning the string represents the currect type of the library
|
returning the string represents the currect type of the library
|
||||||
we have following types:
|
we have following types:
|
||||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
asm_vc_64 - with asm for VC (64 bit)
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
asm_gcc_64 - with asm for GCC (64 bit)
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
const char * UInt<value_size>::LibTypeStr()
|
const char * UInt<value_size>::LibTypeStr()
|
||||||
|
@ -156,12 +157,17 @@ namespace ttmath
|
||||||
and returns a carry (if it was)
|
and returns a carry (if it was)
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
AddInt(2,1)
|
AddInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 + 2;
|
table[1] = 30 + 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -199,17 +205,23 @@ namespace ttmath
|
||||||
x1 - lower word, x2 - higher word
|
x1 - lower word, x2 - higher word
|
||||||
|
|
||||||
for example if we've got value_size equal 4 and:
|
for example if we've got value_size equal 4 and:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4
|
table[1] = 4
|
||||||
table[2] = 5
|
table[2] = 5
|
||||||
table[3] = 6
|
table[3] = 6
|
||||||
|
|
||||||
then let
|
then let
|
||||||
|
|
||||||
x1 = 10
|
x1 = 10
|
||||||
x2 = 20
|
x2 = 20
|
||||||
|
|
||||||
and
|
and
|
||||||
|
|
||||||
index = 1
|
index = 1
|
||||||
|
|
||||||
the result of this method will be:
|
the result of this method will be:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4 + x1 = 14
|
table[1] = 4 + x1 = 14
|
||||||
table[2] = 5 + x2 = 25
|
table[2] = 5 + x2 = 25
|
||||||
|
@ -245,19 +257,20 @@ namespace ttmath
|
||||||
this static method addes one vector to the other
|
this static method addes one vector to the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
|
ss1: ss2: result (output):
|
||||||
|
5 1 5+1
|
||||||
|
4 3 4+3
|
||||||
|
2 7 2+7
|
||||||
|
6 6
|
||||||
|
9 9
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
|
||||||
ss1: ss2: result (output):
|
|
||||||
5 1 5+1
|
|
||||||
4 3 4+3
|
|
||||||
2 7 2+7
|
|
||||||
6 6
|
|
||||||
9 9
|
|
||||||
of course the carry is propagated and will be returned from the last item
|
of course the carry is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
*/
|
*/
|
||||||
|
@ -342,12 +355,17 @@ namespace ttmath
|
||||||
and returns a carry (if it was)
|
and returns a carry (if it was)
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
SubInt(2,1)
|
SubInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 - 2;
|
table[1] = 30 - 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -377,19 +395,19 @@ namespace ttmath
|
||||||
this static method subtractes one vector from the other
|
this static method subtractes one vector from the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
ss1: ss2: result (output):
|
ss1: ss2: result (output):
|
||||||
5 1 5-1
|
5 1 5-1
|
||||||
4 3 4-3
|
4 3 4-3
|
||||||
2 7 2-7
|
2 7 2-7
|
||||||
6 6-1 (the borrow from previous item)
|
6 6-1 (the borrow from previous item)
|
||||||
9 9
|
9 9
|
||||||
return (carry): 0
|
return (carry): 0
|
||||||
of course the carry (borrow) is propagated and will be returned from the last item
|
of course the carry (borrow) is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
|
@ -480,6 +498,8 @@ namespace ttmath
|
||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = (c != 0)? 1 : 0;
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2_one", c)
|
TTMATH_LOGC("UInt::Rcr2_one", c)
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
@ -518,7 +538,7 @@ namespace ttmath
|
||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcl2", c)
|
TTMATH_LOGC("UInt::Rcl2", (c & 1))
|
||||||
|
|
||||||
return (c & 1);
|
return (c & 1);
|
||||||
}
|
}
|
||||||
|
@ -557,9 +577,11 @@ namespace ttmath
|
||||||
c = new_c;
|
c = new_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
||||||
|
|
||||||
TTMATH_LOGC("UInt::Rcr2", c)
|
TTMATH_LOGC("UInt::Rcr2", c)
|
||||||
|
|
||||||
return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -618,9 +640,11 @@ namespace ttmath
|
||||||
bit is from <0,TTMATH_BITS_PER_UINT-1>
|
bit is from <0,TTMATH_BITS_PER_UINT-1>
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
uint x = 100;
|
|
||||||
uint bit = SetBitInWord(x, 3);
|
uint x = 100;
|
||||||
now: x = 108 and bit = 0
|
uint bit = SetBitInWord(x, 3);
|
||||||
|
|
||||||
|
now: x = 108 and bit = 0
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||||
|
@ -653,10 +677,11 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
multiplication: result_high:result_low = a * b
|
multiplication: result_high:result_low = a * b
|
||||||
result_high - higher word of the result
|
- result_high - higher word of the result
|
||||||
result_low - lower word of the result
|
- result_low - lower word of the result
|
||||||
|
|
||||||
this methos never returns a carry
|
this methos never returns a carry
|
||||||
|
|
||||||
this method is used in the second version of the multiplication algorithms
|
this method is used in the second version of the multiplication algorithms
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -35,16 +35,10 @@
|
||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef headerfilettmathuint_x86
|
#ifndef headerfilettmathuint_x86
|
||||||
#define headerfilettmathuint_x86
|
#define headerfilettmathuint_x86
|
||||||
|
|
||||||
|
|
||||||
#ifndef TTMATH_NOASM
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file ttmathuint_x86.h
|
\file ttmathuint_x86.h
|
||||||
\brief template class UInt<uint> with assembler code for 32bit x86 processors
|
\brief template class UInt<uint> with assembler code for 32bit x86 processors
|
||||||
|
@ -53,6 +47,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_NOASM
|
||||||
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief a namespace for the TTMath library
|
\brief a namespace for the TTMath library
|
||||||
|
@ -62,13 +62,14 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returning the string represents the currect type of the library
|
returning the string represents the currect type of the library
|
||||||
|
|
||||||
we have following types:
|
we have following types:
|
||||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
asm_vc_64 - with asm for VC (64 bit)
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
asm_gcc_64 - with asm for GCC (64 bit)
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
const char * UInt<value_size>::LibTypeStr()
|
const char * UInt<value_size>::LibTypeStr()
|
||||||
|
@ -210,12 +211,17 @@ namespace ttmath
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
AddInt(2,1)
|
AddInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 + 2;
|
table[1] = 30 + 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -314,17 +320,23 @@ namespace ttmath
|
||||||
x1 - lower word, x2 - higher word
|
x1 - lower word, x2 - higher word
|
||||||
|
|
||||||
for example if we've got value_size equal 4 and:
|
for example if we've got value_size equal 4 and:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4
|
table[1] = 4
|
||||||
table[2] = 5
|
table[2] = 5
|
||||||
table[3] = 6
|
table[3] = 6
|
||||||
|
|
||||||
then let
|
then let
|
||||||
|
|
||||||
x1 = 10
|
x1 = 10
|
||||||
x2 = 20
|
x2 = 20
|
||||||
|
|
||||||
and
|
and
|
||||||
|
|
||||||
index = 1
|
index = 1
|
||||||
|
|
||||||
the result of this method will be:
|
the result of this method will be:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4 + x1 = 14
|
table[1] = 4 + x1 = 14
|
||||||
table[2] = 5 + x2 = 25
|
table[2] = 5 + x2 = 25
|
||||||
|
@ -653,12 +665,17 @@ namespace ttmath
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
SubInt(2,1)
|
SubInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 - 2;
|
table[1] = 30 - 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -1405,9 +1422,10 @@ namespace ttmath
|
||||||
|
|
||||||
bit is from <0,31>
|
bit is from <0,31>
|
||||||
e.g.
|
e.g.
|
||||||
uint x = 100;
|
|
||||||
uint bit = SetBitInWord(x, 3);
|
uint x = 100;
|
||||||
now: x = 108 and bit = 0
|
uint bit = SetBitInWord(x, 3);
|
||||||
|
now: x = 108 and bit = 0
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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,22 @@
|
||||||
this file is included at the end of ttmathuint.h
|
this file is included at the end of ttmathuint.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
/*!
|
||||||
|
\file ttmathuint_x86_64_msvc.asm
|
||||||
|
\brief some asm routines for x86_64 when using Microsoft compiler
|
||||||
|
|
||||||
|
this file should be first compiled:
|
||||||
|
- compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||||
|
- compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
|
||||||
|
|
||||||
|
this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
||||||
|
|
||||||
|
(you can use win64_assemble.bat file from ttmath subdirectory)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -59,7 +74,7 @@
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifndef __GNUC__
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
@ -92,7 +107,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 +125,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 +164,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
|
||||||
|
|
||||||
|
@ -199,12 +210,17 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
AddInt(2,1)
|
AddInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 + 2;
|
table[1] = 30 + 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -220,12 +236,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
|
||||||
|
|
||||||
|
@ -274,17 +285,23 @@ namespace ttmath
|
||||||
x1 - lower word, x2 - higher word
|
x1 - lower word, x2 - higher word
|
||||||
|
|
||||||
for example if we've got value_size equal 4 and:
|
for example if we've got value_size equal 4 and:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4
|
table[1] = 4
|
||||||
table[2] = 5
|
table[2] = 5
|
||||||
table[3] = 6
|
table[3] = 6
|
||||||
|
|
||||||
then let
|
then let
|
||||||
|
|
||||||
x1 = 10
|
x1 = 10
|
||||||
x2 = 20
|
x2 = 20
|
||||||
|
|
||||||
and
|
and
|
||||||
|
|
||||||
index = 1
|
index = 1
|
||||||
|
|
||||||
the result of this method will be:
|
the result of this method will be:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4 + x1 = 14
|
table[1] = 4 + x1 = 14
|
||||||
table[2] = 5 + x2 = 25
|
table[2] = 5 + x2 = 25
|
||||||
|
@ -304,12 +321,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
|
||||||
|
|
||||||
|
@ -355,19 +367,19 @@ namespace ttmath
|
||||||
this static method addes one vector to the other
|
this static method addes one vector to the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
ss1: ss2: result (output):
|
ss1: ss2: result (output):
|
||||||
5 1 5+1
|
5 1 5+1
|
||||||
4 3 4+3
|
4 3 4+3
|
||||||
2 7 2+7
|
2 7 2+7
|
||||||
6 6
|
6 6
|
||||||
9 9
|
9 9
|
||||||
of course the carry is propagated and will be returned from the last item
|
of course the carry is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
*/
|
*/
|
||||||
|
@ -378,12 +390,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 +463,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
|
||||||
|
|
||||||
|
@ -508,12 +509,17 @@ namespace ttmath
|
||||||
***this method is created only on a 64bit platform***
|
***this method is created only on a 64bit platform***
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
SubInt(2,1)
|
SubInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 - 2;
|
table[1] = 30 - 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -529,12 +535,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
|
||||||
|
|
||||||
|
@ -575,19 +576,19 @@ namespace ttmath
|
||||||
this static method subtractes one vector from the other
|
this static method subtractes one vector from the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
ss1: ss2: result (output):
|
ss1: ss2: result (output):
|
||||||
5 1 5-1
|
5 1 5-1
|
||||||
4 3 4-3
|
4 3 4-3
|
||||||
2 7 2-7
|
2 7 2-7
|
||||||
6 6-1 (the borrow from previous item)
|
6 6-1 (the borrow from previous item)
|
||||||
9 9
|
9 9
|
||||||
return (carry): 0
|
return (carry): 0
|
||||||
of course the carry (borrow) is propagated and will be returned from the last item
|
of course the carry (borrow) is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
|
@ -599,12 +600,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
|
||||||
|
|
||||||
|
@ -682,12 +678,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_rcl_x64(p1,b,c);
|
c = ttmath_rcl_x64(p1,b,c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -742,12 +733,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 +789,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 +861,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
|
||||||
|
|
||||||
|
@ -950,12 +927,7 @@ 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;
|
||||||
|
|
||||||
|
@ -999,12 +971,7 @@ 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 +1024,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
|
||||||
|
|
||||||
|
@ -1097,8 +1060,8 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
multiplication: result_high:result_low = a * b
|
multiplication: result_high:result_low = a * b
|
||||||
result_high - higher word of the result
|
- result_high - higher word of the result
|
||||||
result_low - lower word of the result
|
- result_low - lower word of the result
|
||||||
|
|
||||||
this methos never returns a carry
|
this methos never returns a carry
|
||||||
this method is used in the second version of the multiplication algorithms
|
this method is used in the second version of the multiplication algorithms
|
||||||
|
@ -1118,12 +1081,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 +1140,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;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
;
|
;
|
||||||
; This file is a part of TTMath Bignum Library
|
; This file is a part of TTMath Bignum Library
|
||||||
; and is distributed under the (new) BSD licence.
|
; and is distributed under the 3-Clause BSD Licence.
|
||||||
; Author: Christian Kaiser <chk@online.de>
|
; Author: Christian Kaiser <chk@online.de>, Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
;
|
;
|
||||||
|
|
||||||
;
|
;
|
||||||
; Copyright (c) 2009, Christian Kaiser
|
; Copyright (c) 2009-2017, Christian Kaiser, 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
|
||||||
|
@ -36,11 +36,14 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
;
|
;
|
||||||
; compile with debug info: ml64.exe /Zd /Zi ttmathuint_x86_64_msvc.asm
|
; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||||
; compile without debug info: ml64.exe ttmathuint_x86_64_msvc.asm
|
; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm
|
||||||
; this create ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
||||||
;
|
;
|
||||||
|
|
||||||
|
; doxygen info is put to ttmathuint_x86_64.h file
|
||||||
|
|
||||||
|
|
||||||
PUBLIC ttmath_adc_x64
|
PUBLIC ttmath_adc_x64
|
||||||
PUBLIC ttmath_addindexed_x64
|
PUBLIC ttmath_addindexed_x64
|
||||||
PUBLIC ttmath_addindexed2_x64
|
PUBLIC ttmath_addindexed2_x64
|
||||||
|
@ -151,12 +154,12 @@ ttmath_addindexed2_x64 PROC
|
||||||
; rdx = b (value size)
|
; rdx = b (value size)
|
||||||
; r8 = nPos
|
; r8 = nPos
|
||||||
; r9 = nValue1
|
; r9 = nValue1
|
||||||
; [esp+0x28] = nValue2
|
; [rsp+0x28] = nValue2
|
||||||
|
|
||||||
xor rax, rax ; return value
|
xor rax, rax ; return value
|
||||||
mov r11, rcx ; table
|
mov r11, rcx ; table
|
||||||
sub rdx, r8 ; rdx = remaining count of uints
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
mov r10, [esp+028h] ; r10 = nValue2
|
mov r10, [rsp+028h] ; r10 = nValue2
|
||||||
|
|
||||||
add qword ptr [r11 + r8 * 8], r9
|
add qword ptr [r11 + r8 * 8], r9
|
||||||
lea r8, [r8+1]
|
lea r8, [r8+1]
|
||||||
|
@ -194,9 +197,9 @@ ttmath_addvector_x64 PROC
|
||||||
; rdx = ss2
|
; rdx = ss2
|
||||||
; r8 = ss1_size
|
; r8 = ss1_size
|
||||||
; r9 = ss2_size
|
; r9 = ss2_size
|
||||||
; [esp+0x28] = result
|
; [rsp+0x28] = result
|
||||||
|
|
||||||
mov r10, [esp+028h]
|
mov r10, [rsp+028h]
|
||||||
sub r8, r9
|
sub r8, r9
|
||||||
xor r11, r11 ; r11=0, cf=0
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
@ -316,9 +319,9 @@ ttmath_subvector_x64 PROC
|
||||||
; rdx = ss2
|
; rdx = ss2
|
||||||
; r8 = ss1_size
|
; r8 = ss1_size
|
||||||
; r9 = ss2_size
|
; r9 = ss2_size
|
||||||
; [esp+0x28] = result
|
; [rsp+0x28] = result
|
||||||
|
|
||||||
mov r10, [esp+028h]
|
mov r10, [rsp+028h]
|
||||||
sub r8, r9
|
sub r8, r9
|
||||||
xor r11, r11 ; r11=0, cf=0
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
rem make sure this is a proper path to the 64 bit assembler
|
||||||
|
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\ml64.exe" /c ttmathuint_x86_64_msvc.asm
|
||||||
|
rem ml64.exe will produce ttmathuint_x86_64_msvc.obj which should be added (linked) to your project
|
||||||
|
|
||||||
|
rem or you can assemble with debug info
|
||||||
|
rem ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||||
|
|
||||||
|
rem be nice, most Windows users just click on the file
|
||||||
|
pause
|
Loading…
Reference in New Issue