Compare commits

...

26 Commits

Author SHA1 Message Date
Tomasz Sowa aad580f51e in ASin() and Gamma() there is used SetZeroNan() to suppress a warning about an uninitialized variable (for gcc)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1229 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 16:09:19 +00:00
Tomasz Sowa 3b113374b7 removed: white characters from tests2/Makefile
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1228 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 13:24:37 +00:00
Tomasz Sowa 0f2fcaf547 updated tests2 output for big_64_64 (tests2/big_64_64.expected)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1227 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 13:06:01 +00:00
Tomasz Sowa f88cba2688 fixed: in Parser: there was an error returned when we parsed a string which at the end had a percentage operator e.g. "10+20%"
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1226 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-23 12:38:22 +00:00
Tomasz Sowa 48d694a47f added: some tests for Big<> and Parser<> classes (tests2 directory)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1225 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-15 19:14:08 +00:00
Tomasz Sowa 9a93db39c4 updated doxygen.cfg (clear config generated from 1.8.15 version)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1224 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-10-09 21:00:20 +00:00
Tomasz Sowa f98c434fc4 updated CHANGELOG
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1198 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-07-31 07:21:10 +00:00
Tomasz Sowa 132fa10cd4 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




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1197 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-07-31 07:14:21 +00:00
Tomasz Sowa dcdb1db9ec 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



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1189 e52654a7-88a9-db11-a3e9-0013d4bc506e
2019-04-11 16:14:04 +00:00
Tomasz Sowa d93d5ffd74 some work in the parser and refactoring
added a new math operator: assign
now we can assign a value to a variable (not finished yet)




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1137 e52654a7-88a9-db11-a3e9-0013d4bc506e
2018-10-30 21:04:06 +00:00
Tomasz Sowa 9b279276f2 changed: commentaries to be more doxygen friendly
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1054 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 17:28:38 +00:00
Tomasz Sowa 83b5ab7170 changed: commentaries to be more doxygen friendly
changed: put block characters {...} is some places



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1053 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 17:13:37 +00:00
Tomasz Sowa 35333b1e32 added: makerelease.sh script to generate the source package tarball
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1052 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 15:18:16 +00:00
Tomasz Sowa c73af9c116 - changed info in headers in source files: (new) BSD licence -> 3-Clause BSD Licence
- added svn:ignore in some places




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1051 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 14:51:21 +00:00
Tomasz Sowa f06592376f changed: some return values has been cleaned in ttmathuint.h
(eclipse builtin parser reported errors but actually the code was correct)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1050 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 12:35:50 +00:00
Tomasz Sowa b36821024b changed: in Parser: the last commit has been changed to:
oper.erase(oper.begin() + oper.size() - 1)
	 because oper.pop_back() is available from c++11 



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1049 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-03-12 12:34:01 +00:00
Tomasz Sowa cd740c5924 changed: in Parser: oper.erase( --oper.end() ) changed to oper.pop_back()
to allow use of the STL port
         (reported on the ttmath forum by Sebo)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1047 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-08 09:02:52 +00:00
Tomasz Sowa 46ed8c3108 fixed: in Object::GetValueAndParam() there was value.empty() used instead of value.clear()
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1046 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-08 08:42:02 +00:00
Tomasz Sowa f4f7882387 changed: changed code in some places to remove warnings generated by Visual Studio
added:   file win64_assemble.bat to compile (assemble) *.asm file for Win64



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1045 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-07 20:42:43 +00:00
Tomasz Sowa 86dc01cdee updated: CHANGELOG, COPYRIGHT, doxygen.cfg
added:   directory 'res' with logos
added:   empty directory 'doc'




git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1044 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-07 14:24:58 +00:00
Tomasz Sowa 2067301d1c changed: get rid of some warnings generated by gcc and clang
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1043 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-07 14:19:59 +00:00
Tomasz Sowa e2cdeac423 fixed: in x86_64 asm code (for Win64) there were in some places the esp register used,
there should be rsp used instead
       (reported by Villi on the tttmath forum)



git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1042 e52654a7-88a9-db11-a3e9-0013d4bc506e
2017-02-06 02:13:05 +00:00
Tomasz Sowa 5893ffa9e3 added: CMakeLists.txt files for building samples by using cmake system
submitted by Mateusz Loskot <mateusz at loskot dot net>


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@997 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-11-28 15:59:08 +00:00
Tomasz Sowa b862422bd9 fixed: in Parser: in method SetDegRadGrad(int angle)
there is incorrectly use || operator (the && shoud be used)
       reported by heby on the ttmath forum


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@450 e52654a7-88a9-db11-a3e9-0013d4bc506e
2014-04-04 23:36:48 +00:00
Tomasz Sowa cb15ac0cd8 removed: some warning messages generated by GCC from ttmathuint.h (Mul3Big3)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@441 e52654a7-88a9-db11-a3e9-0013d4bc506e
2013-06-13 21:31:53 +00:00
Tomasz Sowa 77c41e644a corrected: the date in CHANGELOG (2012.12->2012.11)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@438 e52654a7-88a9-db11-a3e9-0013d4bc506e
2012-11-28 16:24:00 +00:00
46 changed files with 32334 additions and 2277 deletions

View File

@ -1,4 +1,23 @@
Version 0.9.3 (2012.12.28):
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

6
CMakeLists.txt Normal file
View File

@ -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)

View File

@ -1,4 +1,4 @@
Copyright (c) 2006-2012, Tomasz Sowa
Copyright (c) 2006-2017, Tomasz Sowa
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
o = main.o
CC = g++
CFLAGS = -s -O2 -DTTMATH_CONSTANTSGENERATOR
CC = clang++
CFLAGS = -O2 -DTTMATH_CONSTANTSGENERATOR
name = gen
@ -13,7 +13,7 @@ name = gen
all: $(name)
$(name): $(o)
$(CC) -o $(name) $(CFLAGS) $(o)
$(CC) -o $(name) -s $(CFLAGS) $(o)

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*

File diff suppressed because it is too large Load Diff

137
makerelease.sh Executable file
View File

@ -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

96
res/ttmath_logo.svg Normal file
View File

@ -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

16
samples/CMakeLists.txt Normal file
View File

@ -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()

View File

@ -1,5 +1,6 @@
CC = g++
CFLAGS = -Wall -pedantic -s -O2 -I.. -DTTMATH_DONT_USE_WCHAR
#CC = clang++
CFLAGS = -Wall -pedantic -O2 -I.. -DTTMATH_DONT_USE_WCHAR
.SUFFIXES: .cpp .o
@ -12,19 +13,19 @@ all: uint int big big2 parser
uint: uint.o
$(CC) -o uint $(CFLAGS) uint.o
$(CC) -o uint -s $(CFLAGS) uint.o
int: int.o
$(CC) -o int $(CFLAGS) int.o
$(CC) -o int -s $(CFLAGS) int.o
big: big.o
$(CC) -o big $(CFLAGS) big.o
$(CC) -o big -s $(CFLAGS) big.o
big2: big2.o
$(CC) -o big2 $(CFLAGS) big2.o
$(CC) -o big2 -s $(CFLAGS) big2.o
parser: parser.o
$(CC) -o parser $(CFLAGS) parser.o
$(CC) -o parser -s $(CFLAGS) parser.o
uint.o: uint.cpp
@ -42,5 +43,5 @@ clean:
rm -f big
rm -f big2
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

View File

@ -1,6 +1,6 @@
CC = g++
CC = clang++
o = main.o uinttest.o
CFLAGS = -Wall -O2 -s
CFLAGS = -Wall -O2
ttmath = ..
name = tests
@ -16,7 +16,7 @@ all: $(name)
$(name): $(o)
$(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o)
$(CC) -o $(name) -s $(CFLAGS) -I$(ttmath) $(o)
main.o: main.cpp uinttest.h

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* and is distributed under the 3-Clause BSD Licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*

133
tests2/Makefile Normal file
View File

@ -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

2161
tests2/big_128_4096.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_128_512.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_256_1024.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_512_2048.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_1024.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_128.expected Normal file

File diff suppressed because it is too large Load Diff

2161
tests2/big_64_192.expected Normal file

File diff suppressed because it is too large Load Diff

2161
tests2/big_64_2048.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_256.expected Normal file

File diff suppressed because it is too large Load Diff

2161
tests2/big_64_4096.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_512.expected Normal file

File diff suppressed because one or more lines are too long

2161
tests2/big_64_64.expected Normal file

File diff suppressed because it is too large Load Diff

31
tests2/check_files.sh Executable file
View File

@ -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

39
tests2/main.cpp Normal file
View File

@ -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;
}

2161
tests2/tests.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
/*
* 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>
*/
/*
* Copyright (c) 2006-2012, Tomasz Sowa
* Copyright (c) 2006-2017, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -79,10 +79,12 @@ namespace ttmath
/*!
this function skips the fraction from x
e.g 2.2 = 2
2.7 = 2
-2.2 = 2
-2.7 = 2
samples
- 2.2 = 2
- 2.7 = 2
- -2.2 = 2
- -2.7 = 2
*/
template<class ValueType>
ValueType SkipFraction(const ValueType & x)
@ -96,10 +98,12 @@ namespace ttmath
/*!
this function rounds to the nearest integer value
e.g 2.2 = 2
2.7 = 3
-2.2 = -2
-2.7 = -3
samples
- 2.2 = 2
- 2.7 = 3
- -2.2 = -2
- -2.7 = -3
*/
template<class ValueType>
ValueType Round(const ValueType & x, ErrorCode * err = 0)
@ -127,12 +131,12 @@ namespace ttmath
this function returns a value representing the smallest integer
that is greater than or equal to x
Ceil(-3.7) = -3
Ceil(-3.1) = -3
Ceil(-3.0) = -3
Ceil(4.0) = 4
Ceil(4.2) = 5
Ceil(4.8) = 5
- Ceil(-3.7) = -3
- Ceil(-3.1) = -3
- Ceil(-3.0) = -3
- Ceil(4.0) = 4
- Ceil(4.2) = 5
- Ceil(4.8) = 5
*/
template<class ValueType>
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
@ -174,12 +178,12 @@ namespace ttmath
this function returns a value representing the largest integer
that is less than or equal to x
Floor(-3.6) = -4
Floor(-3.1) = -4
Floor(-3) = -3
Floor(2) = 2
Floor(2.3) = 2
Floor(2.8) = 2
- Floor(-3.6) = -4
- Floor(-3.1) = -4
- Floor(-3) = -3
- Floor(2) = 2
- Floor(2.3) = 2
- Floor(2.8) = 2
*/
template<class ValueType>
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
@ -346,6 +350,9 @@ namespace ttmath
/*
this namespace consists of auxiliary functions
(something like 'private' in a class)
this is excluded from doxygen documentation
(option EXCLUDE_SYMBOLS in doxygen.cfg)
*/
namespace auxiliaryfunctions
{
@ -866,7 +873,8 @@ namespace ttmath
if( err )
*err = err_improper_argument;
return result; // NaN is set by default
result.SetZeroNan();
return result;
}
if( x.IsSign() )
@ -1611,15 +1619,16 @@ namespace ttmath
minutes and seconds must be greater than or equal zero
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
there's only one division)
for example:
DegToDeg(10, 30, 0) = 10.5
DegToDeg(10, 24, 35.6)=10.4098(8)
samples:
- DegToDeg(10, 30, 0) = 10.5
- DegToDeg(10, 24, 35.6)=10.4098(8)
*/
template<class ValueType>
ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s,
@ -2050,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....)
if index==0 the result is one
if x==0 the result is zero and we assume root(0;0) is not defined
- if index==0 the result is one
- 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 odd (1;2;3;...) the result is either
-(abs(x)^(1/index)) if x<0 or
x^(1/index)) if 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
- -(abs(x)^(1/index)) if x<0, or
- 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>
ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
@ -2119,8 +2129,10 @@ namespace ttmath
/*!
absolute value of x
e.g. -2 = 2
2 = 2
samples:
- -2 = 2
- 2 = 2
*/
template<class ValueType>
ValueType Abs(const ValueType & x)
@ -2134,9 +2146,11 @@ namespace ttmath
/*!
it returns the sign of the value
e.g. -2 = -1
0 = 0
10 = 1
samples:
- -2 = -1
- 0 = 0
- 10 = 1
*/
template<class ValueType>
ValueType Sgn(ValueType x)
@ -2150,11 +2164,11 @@ namespace ttmath
/*!
the remainder from a division
e.g.
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
mod(-12.6 ; -3) = -0.6
samples:
- 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
- mod(-12.6 ; -3) = -0.6
*/
template<class ValueType>
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
@ -2186,7 +2200,8 @@ namespace ttmath
this function is used to store factorials in a given container
'more' means how many values should be added at the end
e.g.
sample:
std::vector<ValueType> fact;
SetFactorialSequence(fact, 3);
// now the container has three values: 1 1 2
@ -2221,7 +2236,8 @@ namespace ttmath
an auxiliary function used to calculate Bernoulli numbers
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
(cgamma.fact should have at least m items)
@ -2275,9 +2291,10 @@ namespace ttmath
an auxiliary function used to calculate Bernoulli numbers
start is >= 2
we use the recurrence formula:
B(m) = 1 / (2*(1 - 2^m)) * sum(m)
where sum(m) is calculated by SetBernoulliNumbersSum()
we use the recurrence formula:
B(m) = 1 / (2*(1 - 2^m)) * sum(m)
where sum(m) is calculated by SetBernoulliNumbersSum()
*/
template<class ValueType>
bool SetBernoulliNumbersMore(CGamma<ValueType> & cgamma, uint start, const volatile StopCalculating * stop = 0)
@ -2330,7 +2347,8 @@ namespace ttmath
returns false if there was a stop signal,
'more' means how many values should be added at the end
e.g.
sample:
typedef Big<1,2> MyBig;
CGamma<MyBig> cgamma;
SetBernoulliNumbers(cgamma, 3);
@ -2377,9 +2395,11 @@ namespace ttmath
an auxiliary function used to calculate the Gamma() function
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) + ...
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>
ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
@ -2440,9 +2460,11 @@ namespace ttmath
an auxiliary function used to calculate the Gamma() function
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)
and sum(n) is calculated by GammaFactorialHighSum()
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)
and sum(n) is calculated by GammaFactorialHighSum()
*/
template<class ValueType>
ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
@ -2494,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 the formula:
gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1)
gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1)
*/
template<class ValueType>
ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & cgamma)
@ -2545,11 +2568,12 @@ namespace ttmath
we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
we use a recurrence formula:
gamma(z+1) = z * gamma(z)
then: gamma(z) = gamma(z+1) / z
e.g.
gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
samples:
- gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
*/
template<class ValueType>
ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
@ -2640,11 +2664,13 @@ namespace ttmath
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma()
e.g.
typedef Big<1,2> MyBig;
MyBig x=234, y=345.53;
CGamma<MyBig> cgamma;
std::cout << Gamma(x, cgamma) << std::endl;
std::cout << Gamma(y, cgamma) << std::endl;
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
and they will be reused in next calls to the function
@ -2685,7 +2711,7 @@ namespace ttmath
if( n.IsZero() )
{
err_tmp = err_improper_argument;
result.SetNan();
result.SetZeroNan();
}
else
{
@ -2768,11 +2794,13 @@ namespace ttmath
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial()
e.g.
typedef Big<1,2> MyBig;
MyBig x=234, y=54345;
CGamma<MyBig> cgamma;
std::cout << Factorial(x, cgamma) << std::endl;
std::cout << Factorial(y, cgamma) << std::endl;
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
and they will be reused in next calls to the function

View File

@ -1,11 +1,11 @@
/*
* 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>
*/
/*
* Copyright (c) 2006-2012, Tomasz Sowa
* Copyright (c) 2006-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -66,19 +66,19 @@ class Big
/*
value = mantissa * 2^exponent
exponent - an integer value with a sign
mantissa - an integer value without a sing
- exponent - an integer value with a sign
- mantissa - an integer value without a sing
mantissa must be pushed into the left side that is the highest bit from
mantissa must be one (of course if there's another value than zero) -- this job
(pushing bits into the left side) making Standardizing() method
(pushing bits into the left side) is doing by Standardizing() method
for example:
if we want to store value one (1) into our Big object we must:
set mantissa to 1
set exponent to 0
set info to 0
and call method Standardizing()
- set mantissa to 1
- set exponent to 0
- set info to 0
- and call method Standardizing()
*/
@ -135,12 +135,12 @@ public:
/*!
returning the string represents the currect type of the library
we have following types:
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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
- 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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
*/
static const char * LibTypeStr()
{
@ -392,6 +392,8 @@ public:
*/
void SetPi()
{
// IMPROVE ME
// give some compiler-time warning when the size of mantissa is greater than the builtin size of the mantissa pi
SetMantissaPi();
info = 0;
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
@ -403,6 +405,8 @@ public:
*/
void Set05Pi()
{
// IMPROVE ME
// give some compiler-time warning when the size of mantissa is greater than the builtin size of the mantissa pi
SetMantissaPi();
info = 0;
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
@ -414,6 +418,8 @@ public:
*/
void Set2Pi()
{
// IMPROVE ME
// give some compiler-time warning when the size of mantissa is greater than the builtin size of the mantissa pi
SetMantissaPi();
info = 0;
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
@ -669,9 +675,9 @@ public:
this method clears the sign
(there'll be an absolute value)
e.g.
-1 -> 1
2 -> 2
samples
- -1 -> 1
- 2 -> 2
*/
void Abs()
{
@ -681,9 +687,11 @@ public:
/*!
this method remains the 'sign' of the value
e.g. -2 = -1
0 = 0
10 = 1
samples
- -2 = -1
- 0 = 0
- 10 = 1
*/
void Sgn()
{
@ -708,9 +716,9 @@ public:
/*!
this method sets the sign
e.g.
-1 -> -1
2 -> -2
samples
- -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
@ -725,9 +733,9 @@ public:
this method changes the sign
when there is a value of zero then the sign is not changed
e.g.
-1 -> 1
2 -> -2
samples
- -1 -> 1
- 2 -> -2
*/
void ChangeSign()
{
@ -750,8 +758,8 @@ private:
this method does the half-to-even rounding (banker's rounding)
if is_half is:
true - that means the rest was equal the half (0.5 decimal)
false - that means the rest was greater than a half (greater than 0.5 decimal)
- true - that means the rest was equal the half (0.5 decimal)
- false - that means the rest was greater than a half (greater than 0.5 decimal)
if the rest was less than a half then don't call this method
(the rounding should does nothing then)
@ -922,7 +930,6 @@ public:
uint Add(Big<exp, man> ss2, bool round = true, bool adding = true)
{
bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
Int<exp> exp_offset( exponent );
uint c = 0;
if( IsNan() || ss2.IsNan() )
@ -931,32 +938,41 @@ public:
if( !adding )
ss2.ChangeSign(); // subtracting
exp_offset.Sub( ss2.exponent );
exp_offset.Abs();
// (1) abs(this) will be >= abs(ss2)
if( SmallerWithoutSignThan(ss2) )
Swap(ss2);
if( ss2.IsZero() )
return 0;
last_bit_set = rest_zero = do_adding = do_rounding = false;
rounding_up = (IsSign() == ss2.IsSign());
Int<exp> exp_offset( exponent );
exp_offset.Sub( ss2.exponent );
AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
if( !exp_offset.Abs() )
{
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
// so the value is the smallest possible integer
// and its Abs would be greater than mantissa size in bits
// so the method AddCheckExponents would do nothing
if( do_adding )
c += AddMantissas(ss2, last_bit_set, rest_zero);
last_bit_set = rest_zero = do_adding = do_rounding = false;
rounding_up = (IsSign() == ss2.IsSign());
if( !round || !last_bit_set )
do_rounding = false;
AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
if( do_rounding )
c += RoundHalfToEven(rest_zero, rounding_up);
if( do_adding )
c += AddMantissas(ss2, last_bit_set, rest_zero);
if( !round || !last_bit_set )
do_rounding = false;
if( do_rounding )
c += RoundHalfToEven(rest_zero, rounding_up);
if( do_adding || do_rounding )
c += Standardizing();
}
if( do_adding || do_rounding )
c += Standardizing();
return CheckCarry(c);
}
@ -977,13 +993,16 @@ public:
bitwise AND
this and ss2 must be >= 0
return values:
0 - ok
1 - carry
2 - this or ss2 was negative
- 0 - ok
- 1 - carry
- 2 - this or ss2 was negative
*/
uint BitAnd(Big<exp, man> ss2)
{
uint c = 0;
if( IsNan() || ss2.IsNan() )
return CheckCarry(1);
@ -1002,20 +1021,20 @@ public:
return 0;
}
Int<exp> exp_offset( exponent );
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
uint c = 0;
exp_offset.Sub( ss2.exponent );
exp_offset.Abs();
// abs(this) will be >= abs(ss2)
if( SmallerWithoutSignThan(ss2) )
Swap(ss2);
if( exp_offset >= mantissa_size_in_bits )
Int<exp> exp_offset( exponent );
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
exp_offset.Sub( ss2.exponent );
if( exp_offset.Abs() || exp_offset >= mantissa_size_in_bits )
{
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
// so the value is the smallest possible integer
// and its Abs would be greater than mantissa size in bits
// the second value is too small
SetZero();
return 0;
@ -1036,12 +1055,15 @@ public:
this and ss2 must be >= 0
return values:
0 - ok
1 - carry
2 - this or ss2 was negative
- 0 - ok
- 1 - carry
- 2 - this or ss2 was negative
*/
uint BitOr(Big<exp, man> ss2)
{
uint c = 0;
if( IsNan() || ss2.IsNan() )
return CheckCarry(1);
@ -1060,21 +1082,23 @@ public:
if( ss2.IsZero() )
return 0;
Int<exp> exp_offset( exponent );
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
uint c = 0;
exp_offset.Sub( ss2.exponent );
exp_offset.Abs();
// abs(this) will be >= abs(ss2)
if( SmallerWithoutSignThan(ss2) )
Swap(ss2);
if( exp_offset >= mantissa_size_in_bits )
Int<exp> exp_offset( exponent );
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
exp_offset.Sub( ss2.exponent );
if( exp_offset.Abs() || exp_offset >= mantissa_size_in_bits )
{
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
// so the value is the smallest possible integer
// and its Abs would be greater than mantissa size in bits
// the second value is too small
return 0;
}
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
@ -1091,12 +1115,15 @@ public:
this and ss2 must be >= 0
return values:
0 - ok
1 - carry
2 - this or ss2 was negative
- 0 - ok
- 1 - carry
- 2 - this or ss2 was negative
*/
uint BitXor(Big<exp, man> ss2)
{
uint c = 0;
if( IsNan() || ss2.IsNan() )
return CheckCarry(1);
@ -1115,21 +1142,23 @@ public:
return 0;
}
Int<exp> exp_offset( exponent );
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
uint c = 0;
exp_offset.Sub( ss2.exponent );
exp_offset.Abs();
// abs(this) will be >= abs(ss2)
if( SmallerWithoutSignThan(ss2) )
Swap(ss2);
if( exp_offset >= mantissa_size_in_bits )
Int<exp> exp_offset( exponent );
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
exp_offset.Sub( ss2.exponent );
if( exp_offset.Abs() || exp_offset >= mantissa_size_in_bits )
{
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
// so the value is the smallest possible integer
// and its Abs would be greater than mantissa size in bits
// the second value is too small
return 0;
}
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
@ -1244,8 +1273,8 @@ private:
call this method only if the highest bit is set - you have to test it beforehand
return:
true - tab was equal the half (0.5 decimal)
false - tab was greater than a half (greater than 0.5 decimal)
- true - tab was equal the half (0.5 decimal)
- false - tab was greater than a half (greater than 0.5 decimal)
*/
bool CheckGreaterOrEqualHalf(uint * tab, uint len)
@ -1361,9 +1390,9 @@ private:
division this = this / ss2
return value:
0 - ok
1 - carry (in a division carry can be as well)
2 - improper argument (ss2 is zero)
- 0 - ok
- 1 - carry (in a division carry can be as well)
- 2 - improper argument (ss2 is zero)
*/
uint DivRef(const Big<exp, man> & ss2, bool round = true)
{
@ -1434,9 +1463,9 @@ public:
division this = this / ss2
return value:
0 - ok
1 - carry (in a division carry can be as well)
2 - improper argument (ss2 is zero)
- 0 - ok
- 1 - carry (in a division carry can be as well)
- 2 - improper argument (ss2 is zero)
*/
uint Div(const Big<exp, man> & ss2, bool round = true)
{
@ -1492,21 +1521,20 @@ private:
public:
/*!
the remainder from a division
caltulate the remainder from a division
e.g.
12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6
-12.6 mod 3 = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
12.6 mod -3 = 0.6
-12.6 mod -3 = -0.6
samples
- 12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6
- -12.6 mod 3 = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
- 12.6 mod -3 = 0.6
- -12.6 mod -3 = -0.6
it means:
in other words: this(old) = ss2 * q + this(new)
return value:
0 - ok
1 - carry
2 - improper argument (ss2 is zero)
- 0 - ok
- 1 - carry
- 2 - improper argument (ss2 is zero)
*/
uint Mod(const Big<exp, man> & ss2)
{
@ -1548,9 +1576,9 @@ public:
binary algorithm (r-to-l)
return values:
0 - ok
1 - carry
2 - incorrect arguments (0^0)
- 0 - ok
- 1 - carry
- 2 - incorrect arguments (0^0)
*/
template<uint pow_size>
uint Pow(UInt<pow_size> pow)
@ -1600,9 +1628,9 @@ public:
p can be negative
return values:
0 - ok
1 - carry
2 - incorrect arguments 0^0 or 0^(-something)
- 0 - ok
- 1 - carry
- 2 - incorrect arguments 0^0 or 0^(-something)
*/
template<uint pow_size>
uint Pow(Int<pow_size> pow)
@ -1640,9 +1668,9 @@ public:
if pow has a fraction the fraction is skipped (not used in calculation)
return values:
0 - ok
1 - carry
2 - incorrect arguments (0^0)
- 0 - ok
- 1 - carry
- 2 - incorrect arguments (0^0)
*/
uint PowUInt(Big<exp, man> pow)
{
@ -1696,9 +1724,9 @@ public:
pow can be negative
return values:
0 - ok
1 - carry
2 - incorrect arguments 0^0 or 0^(-something)
- 0 - ok
- 1 - carry
- 2 - incorrect arguments 0^0 or 0^(-something)
*/
uint PowInt(const Big<exp, man> & pow)
{
@ -1732,9 +1760,9 @@ public:
pow can be negative and with fraction
return values:
0 - ok
1 - carry
2 - incorrect argument ('this' <= 0)
- 0 - ok
- 1 - carry
- 2 - incorrect argument ('this' <= 0)
*/
uint PowFrac(const Big<exp, man> & pow)
{
@ -1762,9 +1790,9 @@ public:
pow can be negative and with fraction
return values:
0 - ok
1 - carry
2 - incorrect argument ('this' or 'pow')
- 0 - ok
- 1 - carry
- 2 - incorrect argument ('this' or 'pow')
*/
uint Pow(const Big<exp, man> & pow)
{
@ -1799,9 +1827,10 @@ public:
this function calculates the square root
e.g. let this=9 then this.Sqrt() gives 3
return: 0 - ok
1 - carry
2 - improper argument (this<0 or NaN)
return:
- 0 - ok
- 1 - carry
- 2 - improper argument (this<0 or NaN)
*/
uint Sqrt()
{
@ -1924,8 +1953,11 @@ public:
Exponent this = exp(x) = e^x
we're using the fact that our value is stored in form of:
x = mantissa * 2^exponent
then
e^x = e^(mantissa* 2^exponent) or
e^x = (e^mantissa)^(2^exponent)
@ -2094,17 +2126,20 @@ public:
(a logarithm with the base equal 'e')
we're using the fact that our value is stored in form of:
x = mantissa * 2^exponent
then
ln(x) = ln (mantissa * 2^exponent) = ln (mantissa) + (exponent * ln (2))
the mantissa we'll show as a value from range <1,2) because the logarithm
is decreasing too fast when 'x' is going to 0
return values:
0 - ok
1 - overflow (carry)
2 - incorrect argument (x<=0)
- 0 - ok
- 1 - overflow (carry)
- 2 - incorrect argument (x<=0)
*/
uint Ln(const Big<exp,man> & x)
{
@ -2142,13 +2177,14 @@ public:
Logarithm from 'x' with a 'base'
we're using the formula:
Log(x) with 'base' = ln(x) / ln(base)
return values:
0 - ok
1 - overflow
2 - incorrect argument (x<=0)
3 - incorrect base (a<=0 lub a=1)
- 0 - ok
- 1 - overflow
- 2 - incorrect argument (x<=0)
- 3 - incorrect base (a<=0 or a=1)
*/
uint Log(const Big<exp,man> & x, const Big<exp,man> & base)
{
@ -2565,21 +2601,21 @@ public:
right. The first bit is the sign bit, S, the next eleven bits are the
exponent bits, 'E', and the final 52 bits are the fraction 'F':
S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0 1 11 12 63
S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0 1 11 12 63
The value V represented by the word may be determined as follows:
* If E=2047 and F is nonzero, then V=NaN ("Not a number")
* If E=2047 and F is zero and S is 1, then V=-Infinity
* If E=2047 and F is zero and S is 0, then V=Infinity
* If 0<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
- If E=2047 and F is nonzero, then V=NaN ("Not a number")
- If E=2047 and F is zero and S is 1, then V=-Infinity
- If E=2047 and F is zero and S is 0, then V=Infinity
- If 0<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
to represent the binary number created by prefixing F with an implicit
leading 1 and a binary point.
* If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
- If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
"unnormalized" values.
* If E=0 and F is zero and S is 1, then V=-0
* If E=0 and F is zero and S is 0, then V=0
- If E=0 and F is zero and S is 1, then V=-0
- If E=0 and F is zero and S is 0, then V=0
*/
#ifdef TTMATH_PLATFORM32
@ -2805,6 +2841,7 @@ public:
if the value is too big:
'result' will be +/-infinity (depending on the sign)
if the value is too small:
'result' will be 0
*/
@ -2832,22 +2869,23 @@ private:
The first bit is the sign bit, S, the next eight bits are the exponent bits, 'E',
and the final 23 bits are the fraction 'F':
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
0 1 8 9 31
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
0 1 8 9 31
The value V represented by the word may be determined as follows:
* If E=255 and F is nonzero, then V=NaN ("Not a number")
* If E=255 and F is zero and S is 1, then V=-Infinity
* If E=255 and F is zero and S is 0, then V=Infinity
* If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent
the binary number created by prefixing F with an implicit leading 1 and a binary point.
* If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
* If E=0 and F is zero and S is 1, then V=-0
* If E=0 and F is zero and S is 0, then V=0
- If E=255 and F is nonzero, then V=NaN ("Not a number")
- If E=255 and F is zero and S is 1, then V=-Infinity
- If E=255 and F is zero and S is 0, then V=Infinity
- If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent
the binary number created by prefixing F with an implicit leading 1 and a binary point.
- If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
- If E=0 and F is zero and S is 1, then V=-0
- If E=0 and F is zero and S is 0, then V=0
*/
bool IsInf(float value) const
{
// CHECK ME
// need testing on a 64 bit machine
union
@ -2875,6 +2913,7 @@ public:
if the value is too big:
'result' will be +/-infinity (depending on the sign)
if the value is too small:
'result' will be 0
*/
@ -2892,11 +2931,12 @@ public:
this method converts from this class into the 'float'
if the value is too big:
'result' will be +/-infinity (depending on the sign)
and the method returns 1
- 'result' will be +/-infinity (depending on the sign)
- and the method returns 1
if the value is too small:
'result' will be 0
and the method returns 1
- 'result' will be 0
- and the method returns 1
*/
uint ToFloat(float & result) const
{
@ -2929,11 +2969,12 @@ public:
this method converts from this class into the 'double'
if the value is too big:
'result' will be +/-infinity (depending on the sign)
and the method returns 1
- 'result' will be +/-infinity (depending on the sign)
- and the method returns 1
if the value is too small:
'result' will be 0
and the method returns 1
- 'result' will be 0
- and the method returns 1
*/
uint ToDouble(double & result) const
{
@ -3666,11 +3707,10 @@ public:
a method for converting into a string
struct Conv is defined in ttmathtypes.h, look there for more information about parameters
output:
return value:
0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
is somewhere an error in the library)
return value:
- 0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
- 1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
is somewhere an error in the library)
*/
uint ToString( std::string & result,
uint base = 10,
@ -4215,10 +4255,12 @@ private:
if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
{
// if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
// it means that we must cut the whole mantissa
// (there'll not be any of the valid bits)
return 1;
}
// e will be from (-man*TTMATH_BITS_PER_UINT, 0>
sint e = -( exponent.ToInt() );
@ -4265,9 +4307,9 @@ private:
a special method used to calculate the new mantissa and exponent
when the 'base' is equal 4, 8 or 16
when base is 4 then bits is 2
when base is 8 then bits is 3
when base is 16 then bits is 4
- when base is 4 then bits is 2
- when base is 8 then bits is 3
- when base is 16 then bits is 4
(and the algorithm can be used with a base greater than 16)
*/
template<class string_type>
@ -5151,7 +5193,10 @@ private:
// we could break the parsing somewhere in the middle of the string,
// but the result (value) still can be good
// we should set a correct value of 'source' now
for( ; Misc::CharToDigit(*source, conv.base) != -1 ; ++source );
while( Misc::CharToDigit(*source, conv.base) != -1 )
{
++source;
}
power_ = power;
c += base_.Pow(power_);
@ -5384,8 +5429,10 @@ public:
}
if( ss2.IsZero() )
{
// this!=0 and ss2==0
return false;
}
// we're using the fact that all bits in mantissa are pushed
// into the left side -- Standardizing()
@ -5408,16 +5455,22 @@ public:
if( IsZero() )
{
if( ss2.IsZero() )
{
// we've got two zeroes
return false;
}
else
{
// this==0 and ss2!=0
return false;
}
}
if( ss2.IsZero() )
{
// this!=0 and ss2==0
return true;
}
// we're using the fact that all bits in mantissa are pushed
// into the left side -- Standardizing()
@ -5440,16 +5493,22 @@ public:
if( IsZero() )
{
if( ss2.IsZero() )
{
// we've got two zeroes
return true;
}
else
{
// this==0 and ss2!=0
return false;
}
}
if( ss2.IsZero() )
{
// this!=0 and ss2==0
return false;
}
if( exponent==ss2.exponent && mantissa==ss2.mantissa )
return true;
@ -5461,12 +5520,16 @@ public:
bool operator<(const Big<exp,man> & ss2) const
{
if( IsSign() && !ss2.IsSign() )
{
// this<0 and ss2>=0
return true;
}
if( !IsSign() && ss2.IsSign() )
{
// this>=0 and ss2<0
return false;
}
// both signs are the same
@ -5489,12 +5552,16 @@ public:
bool operator>(const Big<exp,man> & ss2) const
{
if( IsSign() && !ss2.IsSign() )
{
// this<0 and ss2>=0
return false;
}
if( !IsSign() && ss2.IsSign() )
{
// this>=0 and ss2<0
return true;
}
// both signs are the same
@ -5730,13 +5797,13 @@ public:
/*!
this method makes an integer value by skipping any fractions
for example:
10.7 will be 10
12.1 -- 12
-20.2 -- 20
-20.9 -- 20
-0.7 -- 0
0.8 -- 0
samples:
- 10.7 will be 10
- 12.1 -- 12
- -20.2 -- 20
- -20.9 -- 20
- -0.7 -- 0
- 0.8 -- 0
*/
void SkipFraction()
{
@ -5768,9 +5835,9 @@ public:
/*!
this method remains only a fraction from the value
for example:
30.56 will be 0.56
-12.67 -- -0.67
samples:
- 30.56 will be 0.56
- -12.67 will be -0.67
*/
void RemainFraction()
{
@ -5811,7 +5878,7 @@ public:
this method returns true if the value is integer
(there is no a fraction)
(we don't check nan)
(we don't check NaN)
*/
bool IsInteger() const
{
@ -5853,12 +5920,11 @@ public:
this method rounds to the nearest integer value
(it returns a carry if it was)
for example:
2.3 = 2
2.8 = 3
-2.3 = -2
-2.8 = 3
samples:
- 2.3 = 2
- 2.8 = 3
- -2.3 = -2
- -2.8 = 3
*/
uint Round()
{

View File

@ -1,6 +1,6 @@
/*
* 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>
*/

View File

@ -1,11 +1,11 @@
/*
* 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>
*/
/*
* Copyright (c) 2006-2011, Tomasz Sowa
* Copyright (c) 2006-2017, Tomasz Sowa
* All rights reserved.
*
* 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
value_size - how many bytes specify our value
on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
- on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
- on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
value_size = 1,2,3,4,5,6....
*/
template<uint value_size>
@ -131,8 +131,9 @@ public:
/*!
this method sets the sign
e.g. 1 -> -1
-2 -> -2
samples
- 1 -> -1
- -2 -> -2
from a positive value we make a negative value,
if the value is negative we do nothing
@ -290,10 +291,10 @@ public:
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 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 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 clear
*/
uint Sub(const Int<value_size> & ss2)
{
@ -465,14 +466,14 @@ public:
/*!
division this = this / ss2
returned values:
0 - ok
1 - division by zero
- 0 - ok
- 1 - division by zero
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
*/
@ -509,14 +510,14 @@ public:
/*!
division this = this / ss2 (ss2 is int)
returned values:
0 - ok
1 - division by zero
- 0 - ok
- 1 - division by zero
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
*/
@ -600,9 +601,9 @@ public:
power this = this ^ pow
return values:
0 - ok
1 - carry
2 - incorrect arguments 0^0 or 0^(-something)
- 0 - ok
- 1 - carry
- 2 - incorrect arguments 0^0 or 0^(-something)
*/
uint Pow(Int<value_size> pow)
{
@ -812,7 +813,7 @@ public:
/*!
a copy constructor
*/
Int(const Int<value_size> & u)
Int(const Int<value_size> & u) : UInt<value_size>()
{
FromInt(u);
}

View File

@ -1,6 +1,6 @@
/*
* 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>
*/
@ -171,10 +171,10 @@ static void SkipWhiteCharacters(const char_type * & c)
this static method converts one character into its value
for example:
1 -> 1
8 -> 8
A -> 10
f -> 15
- 1 -> 1
- 8 -> 8
- A -> 10
- f -> 15
this method don't check whether c is correct or not
*/
@ -195,9 +195,9 @@ return c-'A'+10;
(if there can't be a correct value it returns -1)
for example:
c=2, base=10 -> function returns 2
c=A, base=10 -> function returns -1
c=A, base=16 -> function returns 10
- c=2, base=10 -> function returns 2
- c=A, base=10 -> function returns -1
- c=A, base=16 -> function returns 10
*/
static sint CharToDigit(uint c, uint base)
{
@ -228,10 +228,10 @@ return sint(c);
(we don't have to get a base)
for example:
1 -> 1
8 -> 8
10 -> A
15 -> F
- 1 -> 1
- 8 -> 8
- 10 -> A
- 15 -> F
*/
static uint DigitToChar(uint digit)
{

View File

@ -1,11 +1,11 @@
/*
* 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>
*/
/*
* Copyright (c) 2006-2010, Tomasz Sowa
* Copyright (c) 2006-2017, Tomasz Sowa
* All rights reserved.
*
* 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)
int param;
Item() {}
Item() { param = 0; }
Item(const std::string & v, int p) : value(v), param(p) {}
};
@ -484,7 +484,7 @@ public:
if( i == table.end() )
{
value.empty();
value.clear();
*param = 0;
return err_unknown_object;
}
@ -723,14 +723,17 @@ public:
in multithreaded environment you can provide an object of this class to
the Gamma() or Factorial() function, e.g;
typedef Big<1, 3> MyBig;
MyBig x = 123456;
CGamma<MyBig> cgamma;
std::cout << Gamma(x, cgamma);
each thread should have its own CGamma<> object
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;
MyBig x = 123456;
std::cout << Gamma(x);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
* 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>
*/
@ -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
{
@ -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
{
public:
/*!
lock the current thread
it uses a global mutex created by TTMATH_MULTITHREADS_HELPER macro
*/
bool Lock()
{
if( pthread_mutex_lock(&ttmath_mutex) != 0 )

View File

@ -1,11 +1,11 @@
/*
* 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>
*/
/*
* Copyright (c) 2006-2012, Tomasz Sowa
* Copyright (c) 2006-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -64,17 +64,42 @@
/*!
the version of the library
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)
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 9
#define TTMATH_REVISION_VER 3
#define TTMATH_PRERELEASE_VER 0
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
@ -202,16 +227,20 @@ namespace ttmath
#else
/*!
on 64bit platforms one word (uint, sint) will be equal 64bits
*/
#ifdef _MSC_VER
/* in VC 'long' type has 32 bits, __int64 is VC extension */
typedef unsigned __int64 uint;
typedef signed __int64 sint;
#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
/*!
@ -317,12 +346,12 @@ namespace ttmath
/*!
lib type codes:
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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
- 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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
*/
enum LibTypeCode
{
@ -366,7 +395,8 @@ namespace ttmath
err_unknown_object,
err_still_calculating,
err_in_short_form_used_function,
err_percent_from
err_percent_from,
err_assignment_requires_variable
};
@ -407,10 +437,11 @@ namespace ttmath
default: true
e.g.
Conv c;
c.base_round = false;
Big<1, 1> a = "0.1"; // decimal input
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
Conv c;
c.base_round = false;
Big<1, 1> a = "0.1"; // decimal input
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
*/
bool base_round;

View File

@ -1,11 +1,11 @@
/*
* 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>
*/
/*
* Copyright (c) 2006-2011, Tomasz Sowa
* Copyright (c) 2006-2017, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -65,8 +65,8 @@ namespace ttmath
\brief UInt implements a big integer value without a sign
value_size - how many bytes specify our value
on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
- on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
- on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
value_size = 1,2,3,4,5,6....
*/
template<uint value_size>
@ -637,13 +637,13 @@ public:
this method looks for the highest set bit
result:
if 'this' is not zero:
return value - true
'table_id' - the index of a word <0..value_size-1>
- if 'this' is not zero:
return value - true,
'table_id' - the index of a word <0..value_size-1>,
'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
if 'this' is zero:
return value - false
- if 'this' is zero:
return value - false,
both 'table_id' and 'index' are zero
*/
bool FindLeadingBit(uint & table_id, uint & index) const
@ -669,13 +669,13 @@ public:
this method looks for the smallest set bit
result:
if 'this' is not zero:
return value - true
'table_id' - the index of a word <0..value_size-1>
- if 'this' is not zero:
return value - true,
'table_id' - the index of a word <0..value_size-1>,
'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
if 'this' is zero:
return value - false
- if 'this' is zero:
return value - false,
both 'table_id' and 'index' are zero
*/
bool FindLowestBit(uint & table_id, uint & index) const
@ -955,17 +955,20 @@ public:
switch( algorithm )
{
case 1:
return Mul1Big(ss2, result);
Mul1Big(ss2, result);
break;
case 2:
return Mul2Big(ss2, result);
Mul2Big(ss2, result);
break;
case 3:
return Mul3Big(ss2, result);
Mul3Big(ss2, result);
break;
case 100:
default:
return MulFastestBig(ss2, result);
MulFastestBig(ss2, result);
}
}
@ -1184,17 +1187,23 @@ public:
Karatsuba multiplication:
Assume we have:
this = x = x1*B^m + x0
ss2 = y = y1*B^m + y0
where x0 and y0 are less than B^m
the product from multiplication we can show as:
x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
where
z2 = x1*y1
z1 = x1*y0 + x0*y1
z0 = x0*y0
z0 = x0*y0
this is standard schoolbook algorithm with O(n^2), Karatsuba observed that z1 can be given in other form:
z1 = (x1 + x0)*(y1 + y0) - z2 - z0 / z1 = (x1*y1 + x1*y0 + x0*y1 + x0*y0) - x1*y1 - x0*y0 = x1*y0 + x0*y1 /
and to calculate the multiplication we need only three multiplications (with some additions and subtractions)
Our objects 'this' and 'ss2' we divide into two parts and by using recurrence we calculate the multiplication.
@ -1313,6 +1322,11 @@ private:
//we have the stop point in Mul3Big2() method
#endif
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
/*!
an auxiliary method for calculating the Karatsuba multiplication
@ -1447,6 +1461,9 @@ private:
}
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning (default : 4717)
@ -1493,7 +1510,10 @@ public:
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
{
if( value_size < TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
return Mul2Big(ss2, result);
{
Mul2Big(ss2, result);
return;
}
uint x1size = value_size, x2size = value_size;
uint x1start = 0, x2start = 0;
@ -1515,9 +1535,12 @@ public:
uint distancex2 = x2size - x2start;
if( distancex1 < 3 || distancex2 < 3 )
{
// either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
// (this condition in the future can be improved)
return Mul2Big3<value_size>(table, ss2.table, result, x1start, x1size, x2start, x2size);
Mul2Big3<value_size>(table, ss2.table, result, x1start, x1size, x2start, x2size);
return;
}
// Karatsuba multiplication
@ -1595,10 +1618,10 @@ public:
division this = this / ss2
return values:
0 - ok
1 - division by zero
'this' will be the quotient
'remainder' - remainder
- 0 - ok
- 1 - division by zero
- 'this' will be the quotient
- 'remainder' - remainder
*/
uint Div( const UInt<value_size> & divisor,
UInt<value_size> * remainder = 0,
@ -1629,9 +1652,9 @@ private:
/*!
return values:
0 - none has to be done
1 - division by zero
2 - division should be made
- 0 - none has to be done
- 1 - division by zero
- 2 - division should be made
*/
uint Div_StandardTest( const UInt<value_size> & v,
uint & m, uint & n,
@ -1677,13 +1700,13 @@ private:
/*!
return values:
0 - ok
'm' - is the index (from 0) of last non-zero word in table ('this')
'n' - is the index (from 0) of last non-zero word in v.table
1 - v is zero
2 - 'this' is zero
3 - 'this' is smaller than v
4 - 'this' is equal v
- 0 - ok
- 'm' - is the index (from 0) of last non-zero word in table ('this')
- 'n' - is the index (from 0) of last non-zero word in v.table
- 1 - v is zero
- 2 - 'this' is zero
- 3 - 'this' is smaller than v
- 4 - 'this' is equal v
if the return value is different than zero the 'm' and 'n' are undefined
*/
@ -1724,7 +1747,7 @@ public:
/*!
the first division algorithm
radix 2
(radix 2)
*/
uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
{
@ -1747,7 +1770,7 @@ public:
/*!
the first division algorithm
radix 2
(radix 2)
*/
uint Div1(const UInt<value_size> & divisor, UInt<value_size> & remainder)
{
@ -1833,8 +1856,8 @@ public:
the second division algorithm
return values:
0 - ok
1 - division by zero
- 0 - ok
- 1 - division by zero
*/
uint Div2(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
{
@ -1854,8 +1877,8 @@ public:
the second division algorithm
return values:
0 - ok
1 - division by zero
- 0 - ok
- 1 - division by zero
*/
uint Div2(const UInt<value_size> & divisor, UInt<value_size> & remainder)
{
@ -1869,8 +1892,8 @@ private:
the second division algorithm
return values:
0 - ok
1 - division by zero
- 0 - ok
- 1 - division by zero
*/
uint Div2Ref(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
{
@ -1901,9 +1924,9 @@ private:
/*!
return values:
0 - we've calculated the division
1 - division by zero
2 - we have to still calculate
- 0 - we've calculated the division
- 1 - division by zero
- 2 - we have to still calculate
*/
uint Div2_Calculate(const UInt<value_size> & divisor, UInt<value_size> * remainder,
@ -1945,9 +1968,9 @@ private:
/*!
return values:
0 - we've calculated the division
1 - division by zero
2 - we have to still calculate
- 0 - we've calculated the division
- 1 - division by zero
- 2 - we have to still calculate
*/
uint Div2_FindLeadingBitsAndCheck( const UInt<value_size> & divisor,
UInt<value_size> * remainder,
@ -2014,7 +2037,7 @@ private:
/*!
return values:
true if divisor is equal or greater than 'this'
- true if divisor is equal or greater than 'this'
*/
bool Div2_DivisorGreaterOrEqual( const UInt<value_size> & divisor,
UInt<value_size> * remainder,
@ -2261,8 +2284,8 @@ private:
the bits from 'this' we're moving the same times as 'v')
return values:
d - how many times we've moved
return - the next-left value from 'this' (that after table[value_size-1])
- d - how many times we've moved
- return - the next-left value from 'this' (that after table[value_size-1])
*/
uint Div3_Normalize(UInt<value_size> & v, uint n, uint & d)
{
@ -2395,9 +2418,9 @@ public:
binary algorithm (r-to-l)
return values:
0 - ok
1 - carry
2 - incorrect argument (0^0)
- 0 - ok
- 1 - carry
- 2 - incorrect argument (0^0)
*/
uint Pow(UInt<value_size> pow)
{
@ -2475,6 +2498,7 @@ public:
/*!
this method sets n first bits to value zero
@ -3310,7 +3334,7 @@ public:
if( negative )
result = '-';
digits_d = table_id; // for not making an overflow in uint type
digits_d = static_cast<double>(table_id); // for not making an overflow in uint type
digits_d *= TTMATH_BITS_PER_UINT;
digits_d += index + 1;
digits_d *= ToStringLog2(b);
@ -4140,7 +4164,7 @@ public:
/*!
this specialization is needed in order to not confused the compiler "error: ISO C++ forbids zero-size array"
this specialization is needed in order to not confuse the compiler "error: ISO C++ forbids zero-size array"
when compiling Mul3Big2() method
*/
template<>

View File

@ -1,6 +1,6 @@
/*
* 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>
*/
@ -39,15 +39,16 @@
#define headerfilettmathuint_noasm
#ifdef TTMATH_NOASM
/*!
\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
*/
#ifdef TTMATH_NOASM
namespace ttmath
{
@ -55,12 +56,12 @@ namespace ttmath
/*!
returning the string represents the currect type of the library
we have following types:
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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
- 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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
*/
template<uint value_size>
const char * UInt<value_size>::LibTypeStr()
@ -156,12 +157,17 @@ namespace ttmath
and returns a carry (if it was)
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
table[2] = 5;
and we call:
AddInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 + 2;
table[2] = 5;
@ -199,17 +205,23 @@ namespace ttmath
x1 - lower word, x2 - higher word
for example if we've got value_size equal 4 and:
table[0] = 3
table[1] = 4
table[2] = 5
table[3] = 6
then let
x1 = 10
x2 = 20
and
index = 1
the result of this method will be:
table[0] = 3
table[1] = 4 + x1 = 14
table[2] = 5 + x2 = 25
@ -245,19 +257,20 @@ namespace ttmath
this static method addes one vector to the other
'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector
ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size)
- ss1 points to the first (larger) vector
- ss2 points to the second vector
- ss1_size - size of the ss1 (and size of the result too)
- ss2_size - size of the ss2
- 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
(this method is used by the Karatsuba multiplication algorithm)
*/
@ -342,12 +355,17 @@ namespace ttmath
and returns a carry (if it was)
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
and we call:
SubInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 - 2;
table[2] = 5;
@ -377,19 +395,19 @@ namespace ttmath
this static method subtractes one vector from the other
'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector
ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size)
- ss1 points to the first (larger) vector
- ss2 points to the second vector
- ss1_size - size of the ss1 (and size of the result too)
- ss2_size - size of the ss2
- 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-1 (the borrow from previous item)
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-1 (the borrow from previous item)
9 9
return (carry): 0
of course the carry (borrow) is propagated and will be returned from the last item
(this method is used by the Karatsuba multiplication algorithm)
@ -622,9 +640,11 @@ namespace ttmath
bit is from <0,TTMATH_BITS_PER_UINT-1>
e.g.
uint x = 100;
uint bit = SetBitInWord(x, 3);
now: x = 108 and bit = 0
uint x = 100;
uint bit = SetBitInWord(x, 3);
now: x = 108 and bit = 0
*/
template<uint value_size>
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
@ -657,10 +677,11 @@ namespace ttmath
/*!
multiplication: result_high:result_low = a * b
result_high - higher word of the result
result_low - lower word of the result
- result_high - higher word of the result
- result_low - lower word of the result
this methos never returns a carry
this method is used in the second version of the multiplication algorithms
*/
template<uint value_size>

View File

@ -1,6 +1,6 @@
/*
* 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>
*/
@ -35,16 +35,10 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef headerfilettmathuint_x86
#define headerfilettmathuint_x86
#ifndef TTMATH_NOASM
#ifdef TTMATH_PLATFORM32
/*!
\file ttmathuint_x86.h
\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
@ -62,13 +62,14 @@ namespace ttmath
/*!
returning the string represents the currect type of the library
we have following types:
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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
- 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_vc_64 - with asm for VC (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_64 - pure C++ version (64 bit) - without any asm code
*/
template<uint value_size>
const char * UInt<value_size>::LibTypeStr()
@ -210,12 +211,17 @@ namespace ttmath
e.g.
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
table[2] = 5;
and we call:
AddInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 + 2;
table[2] = 5;
@ -314,17 +320,23 @@ namespace ttmath
x1 - lower word, x2 - higher word
for example if we've got value_size equal 4 and:
table[0] = 3
table[1] = 4
table[2] = 5
table[3] = 6
then let
x1 = 10
x2 = 20
and
index = 1
the result of this method will be:
table[0] = 3
table[1] = 4 + x1 = 14
table[2] = 5 + x2 = 25
@ -653,12 +665,17 @@ namespace ttmath
e.g.
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
and we call:
SubInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 - 2;
table[2] = 5;
@ -1405,9 +1422,10 @@ namespace ttmath
bit is from <0,31>
e.g.
uint x = 100;
uint bit = SetBitInWord(x, 3);
now: x = 108 and bit = 0
uint x = 100;
uint bit = SetBitInWord(x, 3);
now: x = 108 and bit = 0
*/
template<uint value_size>
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)

View File

@ -1,6 +1,6 @@
/*
* 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>
*/
@ -51,6 +51,21 @@
this file is included at the end of ttmathuint.h
*/
/*!
\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>
#endif
@ -195,12 +210,17 @@ namespace ttmath
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
table[2] = 5;
and we call:
AddInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 + 2;
table[2] = 5;
@ -265,17 +285,23 @@ namespace ttmath
x1 - lower word, x2 - higher word
for example if we've got value_size equal 4 and:
table[0] = 3
table[1] = 4
table[2] = 5
table[3] = 6
then let
x1 = 10
x2 = 20
and
index = 1
the result of this method will be:
table[0] = 3
table[1] = 4 + x1 = 14
table[2] = 5 + x2 = 25
@ -341,19 +367,19 @@ namespace ttmath
this static method addes one vector to the other
'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector
ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size)
- ss1 points to the first (larger) vector
- ss2 points to the second vector
- ss1_size - size of the ss1 (and size of the result too)
- ss2_size - size of the ss2
- 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
(this method is used by the Karatsuba multiplication algorithm)
*/
@ -483,12 +509,17 @@ namespace ttmath
***this method is created only on a 64bit platform***
if we've got (value_size=3):
table[0] = 10;
table[1] = 30;
table[2] = 5;
and we call:
SubInt(2,1)
then it'll be:
table[0] = 10;
table[1] = 30 - 2;
table[2] = 5;
@ -545,19 +576,19 @@ namespace ttmath
this static method subtractes one vector from the other
'ss1' is larger in size or equal to 'ss2'
ss1 points to the first (larger) vector
ss2 points to the second vector
ss1_size - size of the ss1 (and size of the result too)
ss2_size - size of the ss2
result - is the result vector (which has size the same as ss1: ss1_size)
- ss1 points to the first (larger) vector
- ss2 points to the second vector
- ss1_size - size of the ss1 (and size of the result too)
- ss2_size - size of the ss2
- 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-1 (the borrow from previous item)
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-1 (the borrow from previous item)
9 9
return (carry): 0
of course the carry (borrow) is propagated and will be returned from the last item
(this method is used by the Karatsuba multiplication algorithm)
@ -1029,8 +1060,8 @@ namespace ttmath
/*!
multiplication: result_high:result_low = a * b
result_high - higher word of the result
result_low - lower word of the result
- result_high - higher word of the result
- result_low - lower word of the result
this methos never returns a carry
this method is used in the second version of the multiplication algorithms

View File

@ -1,11 +1,11 @@
;
; This file is a part of TTMath Bignum Library
; and is distributed under the (new) BSD licence.
; Author: Christian Kaiser <chk@online.de>
; and is distributed under the 3-Clause BSD Licence.
; 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.
;
; Redistribution and use in source and binary forms, with or without
@ -41,6 +41,9 @@
; 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_addindexed_x64
PUBLIC ttmath_addindexed2_x64
@ -151,12 +154,12 @@ ttmath_addindexed2_x64 PROC
; rdx = b (value size)
; r8 = nPos
; r9 = nValue1
; [esp+0x28] = nValue2
; [rsp+0x28] = nValue2
xor rax, rax ; return value
mov r11, rcx ; table
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
lea r8, [r8+1]
@ -194,9 +197,9 @@ ttmath_addvector_x64 PROC
; rdx = ss2
; r8 = ss1_size
; r9 = ss2_size
; [esp+0x28] = result
; [rsp+0x28] = result
mov r10, [esp+028h]
mov r10, [rsp+028h]
sub r8, r9
xor r11, r11 ; r11=0, cf=0
@ -316,9 +319,9 @@ ttmath_subvector_x64 PROC
; rdx = ss2
; r8 = ss1_size
; r9 = ss2_size
; [esp+0x28] = result
; [rsp+0x28] = result
mov r10, [esp+028h]
mov r10, [rsp+028h]
sub r8, r9
xor r11, r11 ; r11=0, cf=0

View File

@ -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