Compare commits
26 Commits
Author | SHA1 | Date |
---|---|---|
Tomasz Sowa | aad580f51e | |
Tomasz Sowa | 3b113374b7 | |
Tomasz Sowa | 0f2fcaf547 | |
Tomasz Sowa | f88cba2688 | |
Tomasz Sowa | 48d694a47f | |
Tomasz Sowa | 9a93db39c4 | |
Tomasz Sowa | f98c434fc4 | |
Tomasz Sowa | 132fa10cd4 | |
Tomasz Sowa | dcdb1db9ec | |
Tomasz Sowa | d93d5ffd74 | |
Tomasz Sowa | 9b279276f2 | |
Tomasz Sowa | 83b5ab7170 | |
Tomasz Sowa | 35333b1e32 | |
Tomasz Sowa | c73af9c116 | |
Tomasz Sowa | f06592376f | |
Tomasz Sowa | b36821024b | |
Tomasz Sowa | cd740c5924 | |
Tomasz Sowa | 46ed8c3108 | |
Tomasz Sowa | f4f7882387 | |
Tomasz Sowa | 86dc01cdee | |
Tomasz Sowa | 2067301d1c | |
Tomasz Sowa | e2cdeac423 | |
Tomasz Sowa | 5893ffa9e3 | |
Tomasz Sowa | b862422bd9 | |
Tomasz Sowa | cb15ac0cd8 | |
Tomasz Sowa | 77c41e644a |
21
CHANGELOG
21
CHANGELOG
|
@ -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)
|
* fixed: in Big::FromDouble(double value) (only 32 bit version)
|
||||||
buffer overflow in referencing to UInt<2>
|
buffer overflow in referencing to UInt<2>
|
||||||
this was used when 'value' was in so called "unnormalized" state
|
this was used when 'value' was in so called "unnormalized" state
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# CMake configuration for ttmath
|
||||||
|
cmake_minimum_required (VERSION 3.0)
|
||||||
|
project(ttmath)
|
||||||
|
enable_testing()
|
||||||
|
include_directories(${ttmath_SOURCE_DIR})
|
||||||
|
add_subdirectory(samples)
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2006-2012, Tomasz Sowa
|
Copyright (c) 2006-2017, Tomasz Sowa
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
o = main.o
|
o = main.o
|
||||||
CC = g++
|
CC = clang++
|
||||||
CFLAGS = -s -O2 -DTTMATH_CONSTANTSGENERATOR
|
CFLAGS = -O2 -DTTMATH_CONSTANTSGENERATOR
|
||||||
name = gen
|
name = gen
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ name = gen
|
||||||
all: $(name)
|
all: $(name)
|
||||||
|
|
||||||
$(name): $(o)
|
$(name): $(o)
|
||||||
$(CC) -o $(name) $(CFLAGS) $(o)
|
$(CC) -o $(name) -s $(CFLAGS) $(o)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
3749
doxygen.cfg
3749
doxygen.cfg
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
a=""
|
||||||
|
b=""
|
||||||
|
c=""
|
||||||
|
p=""
|
||||||
|
d=""
|
||||||
|
doxygen=""
|
||||||
|
|
||||||
|
# reading until not empty
|
||||||
|
|
||||||
|
while [ -z $a ]
|
||||||
|
do
|
||||||
|
echo -n "Major: " ; read a
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $b ]
|
||||||
|
do
|
||||||
|
echo -n "Minor: " ; read b;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $c ]
|
||||||
|
do
|
||||||
|
echo -n "Revision: " ; read c;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $p ]
|
||||||
|
do
|
||||||
|
echo -n "Prerelease? (y/n): " ; read p;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $d ]
|
||||||
|
do
|
||||||
|
echo -n "Add date? (y/n): " ; read d;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while [ -z $doxygen ]
|
||||||
|
do
|
||||||
|
echo -n "Clean make and add to the package doxygen doc? (y/n): " ; read doxygen;
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
mkdir -p releases
|
||||||
|
package_dir_name="ttmath-$a.$b.$c"
|
||||||
|
datestr=""
|
||||||
|
|
||||||
|
|
||||||
|
if [ $p = "y" -o $p = "Y" ]
|
||||||
|
then
|
||||||
|
package_dir_name=${package_dir_name}.prerelease
|
||||||
|
fi
|
||||||
|
|
||||||
|
package_dir_name=${package_dir_name}-src
|
||||||
|
|
||||||
|
if [ $d = "y" -o $d = "Y" ]
|
||||||
|
then
|
||||||
|
datestr=`/bin/date "+%G.%m.%d"`;
|
||||||
|
package_dir_name=${package_dir_name}-$datestr
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dir="releases/"${package_dir_name}
|
||||||
|
package=${package_dir_name}.tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
if [ -d $dir ]
|
||||||
|
then
|
||||||
|
echo "Directory $dir exists! (exiting)";
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "releases/"${package} ] ; then
|
||||||
|
echo "File releases/${package} exists! (exiting)"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
mkdir $dir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ $doxygen = "y" -o $doxygen = "Y" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "creating doxygen doc"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
rm -rf doc/doxygen
|
||||||
|
doxygen doxygen.cfg
|
||||||
|
|
||||||
|
cp -r doc $dir/
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "make clean in samples"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
make -C samples clean
|
||||||
|
make -C constgen clean
|
||||||
|
|
||||||
|
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
echo "making source package"
|
||||||
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
|
mkdir $dir/ttmath
|
||||||
|
mkdir $dir/samples
|
||||||
|
mkdir $dir/res
|
||||||
|
|
||||||
|
cp ttmath/* $dir/ttmath/
|
||||||
|
|
||||||
|
cp samples/* $dir/samples/
|
||||||
|
# cmake is not ready yet (cmake will generate Makefile which overwrites our own one)
|
||||||
|
rm $dir/samples/CMakeLists.txt
|
||||||
|
|
||||||
|
cp COPYRIGHT $dir/
|
||||||
|
cp README $dir/
|
||||||
|
cp CHANGELOG $dir/
|
||||||
|
|
||||||
|
cp res/ttmath_logo.svg $dir/res/
|
||||||
|
|
||||||
|
cd releases
|
||||||
|
tar -czf $package ${package_dir_name}
|
||||||
|
|
||||||
|
echo "the package has been created to:" releases/${package}
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="38.084499"
|
||||||
|
height="38.083"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="ttmath_logo.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.2"
|
||||||
|
inkscape:cx="24.511255"
|
||||||
|
inkscape:cy="17.621314"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="830"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-350.08291,-424.26987)">
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 369.125,424.28125 c -10.50699,0 -19.03125,8.52426 -19.03125,19.03125 0,10.50603 8.52426,19.03125 19.03125,19.03125 10.50746,0 19.03125,-8.52522 19.03125,-19.03125 0,-10.50699 -8.52379,-19.03125 -19.03125,-19.03125 z"
|
||||||
|
id="path3773" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffaa35;fill-opacity:1;stroke:none;stroke-width:1.62500000000000000;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 369.125,425.90625 c 9.62928,0 17.40625,7.77748 17.40625,17.40625 0,9.62773 -7.77697,17.40625 -17.40625,17.40625 -9.62877,0 -17.40625,-7.77852 -17.40625,-17.40625 0,-9.62877 7.77748,-17.40625 17.40625,-17.40625 z"
|
||||||
|
id="path2999-2" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 368.1875,432.65625 -0.1875,0.5 -6.34375,16.71875 -1.40625,-4 -0.5,-1.40625 -0.84375,1.25 -2.0625,3.125 1.25,0.8125 1.25,-1.875 1.5625,4.53125 0.6875,1.9375 0.71875,-1.9375 6.90625,-18.15625 8.65625,0 0,-1.5 -9.15625,0 -0.53125,0 z"
|
||||||
|
id="path3003-3"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 359.84375,434.34375 0,3 -3,0 0,1.5 3,0 0,3.21875 1.5,0 0,-3.21875 3,0 0,-1.5 -3,0 0,-3 -1.5,0 z"
|
||||||
|
id="path3005-3"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 371.0625,443.5625 0,0.46875 -0.125,4.6875 0,0.15625 0.125,0.15625 c 0,0 0.37411,0.46147 0.9375,0.9375 0.2817,0.23802 0.59509,0.49145 0.96875,0.6875 0.37366,0.19605 0.8013,0.32003 1.25,0.34375 0.93515,0.0491 1.77613,-0.36791 2.40625,-0.78125 0.63012,-0.41334 1.0625,-0.84375 1.0625,-0.84375 l 0.125,-0.15625 0,-0.1875 -0.0937,-5 0,-0.46875 -0.46875,0 -5.71875,0 -0.46875,0 z"
|
||||||
|
id="path3009-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccsscsccccccccc" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.9375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 377.65625,450.375 -0.0312,0.0312 -0.21875,0.125 c -2.30252,1.65271 -4.15395,1.52806 -6.1125,-0.1562 -1.78014,2.66032 -3.73192,7.25254 -4.29375,8.18745 -0.56183,0.93491 -0.17739,2.37424 -0.28125,3.375 l 0.5625,-0.0312 8.03125,-0.71875 0.125,-0.0312 0.0937,-0.0625 6.96875,-4.5625 0.1875,-0.125 0.0937,-0.0625 -0.0625,-0.3125 c 0.0108,-0.11043 0.0366,-0.43638 0,-0.96875 -0.0466,-1.03041 -0.48309,-1.60724 -0.93745,-2.24995 -0.5467,-0.58055 -1.33798,-1.08483 -2.15625,-1.5 -0.91162,-0.46254 -1.66155,-0.7891 -1.71875,-0.8125 l -0.0625,-0.0312 -0.1875,-0.0937 z"
|
||||||
|
id="path3013-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccczcccccccccccscccc" />
|
||||||
|
<path
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#231f20;fill-opacity:1;stroke:none;stroke-width:0.625;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
d="m 374.0625,438.21875 c -1.68685,0.1362 -5.3125,0.8125 -5.3125,0.8125 l -0.125,0.0312 -0.0625,0.125 -1.375,2.09375 -0.0312,0.0625 0,0.0937 0.1875,6.15625 0.0312,0.15625 0.125,0.0937 0.3125,0.21875 0.5,0.3125 -0.0312,-0.59375 -0.0937,-5.90625 c 0.081,-0.0694 0.35604,-0.32331 0.6875,-0.4375 l 0.0312,0 c 0.0323,-0.01 0.0883,0.01 0.125,0 l 1.46875,-0.0937 c 0.1093,0.60186 0.39332,1.20774 0.4812,1.8125 1.27397,-0.0782 2.40491,-0.17552 3.5031,-0.16892 1.08715,0.0103 2.17115,0.13001 3.2344,0.12517 l 0.0312,-0.6125 c 0,0 0.0422,-0.16533 0.0625,-0.28125 l 0.40625,-0.9375 c 0.004,-0.005 -0.004,-0.0267 0,-0.0312 l 0.0312,0 c 0.17093,-0.1709 0.53319,-0.25585 0.8125,-0.375 0.26159,-0.11159 0.42068,-0.28594 0.75,-0.375 l 0.0312,0 0.125,-0.0312 2.28125,-0.1875 0.0312,0 0.28125,0 0,-0.0312 0,-0.28125 0,-0.71875 0,-0.25 -0.25,-0.0625 -3.75,-0.71875 c -0.0114,-10e-4 -0.02,0.001 -0.0312,0 -1.37083,-0.13192 -2.78705,-0.1247 -4.40625,0 l -0.0312,0 -0.0312,0 z"
|
||||||
|
id="path3017-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccccccccccccccccccccsccccccccccccccccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,16 @@
|
||||||
|
# CMake configuration for ttmath/samples
|
||||||
|
|
||||||
|
# Building with Visual C++ x86_64 needs to compile the asm utilities first
|
||||||
|
if (MSVC AND "x${CMAKE_VS_PLATFORM_NAME}" STREQUAL "xx64")
|
||||||
|
set(TTMATH_MSVC64_ASM ttmathuint_x86_64_msvc.asm)
|
||||||
|
enable_language(ASM_MASM)
|
||||||
|
message(STATUS "Enabled MASM to compile '${TTMATH_MSVC64_ASM}'")
|
||||||
|
set(TTMATH_SRC_ASM ${ttmath_SOURCE_DIR}/ttmath/${TTMATH_MSVC64_ASM})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(SAMPLES big big2 int uint parser)
|
||||||
|
foreach(sample ${SAMPLES})
|
||||||
|
add_executable(${sample} ${sample}.cpp ${TTMATH_SRC_ASM})
|
||||||
|
# Allow to run all utilities at once as a test
|
||||||
|
add_test(${sample} ${sample})
|
||||||
|
endforeach()
|
|
@ -1,5 +1,6 @@
|
||||||
CC = g++
|
CC = g++
|
||||||
CFLAGS = -Wall -pedantic -s -O2 -I.. -DTTMATH_DONT_USE_WCHAR
|
#CC = clang++
|
||||||
|
CFLAGS = -Wall -pedantic -O2 -I.. -DTTMATH_DONT_USE_WCHAR
|
||||||
|
|
||||||
|
|
||||||
.SUFFIXES: .cpp .o
|
.SUFFIXES: .cpp .o
|
||||||
|
@ -12,19 +13,19 @@ all: uint int big big2 parser
|
||||||
|
|
||||||
|
|
||||||
uint: uint.o
|
uint: uint.o
|
||||||
$(CC) -o uint $(CFLAGS) uint.o
|
$(CC) -o uint -s $(CFLAGS) uint.o
|
||||||
|
|
||||||
int: int.o
|
int: int.o
|
||||||
$(CC) -o int $(CFLAGS) int.o
|
$(CC) -o int -s $(CFLAGS) int.o
|
||||||
|
|
||||||
big: big.o
|
big: big.o
|
||||||
$(CC) -o big $(CFLAGS) big.o
|
$(CC) -o big -s $(CFLAGS) big.o
|
||||||
|
|
||||||
big2: big2.o
|
big2: big2.o
|
||||||
$(CC) -o big2 $(CFLAGS) big2.o
|
$(CC) -o big2 -s $(CFLAGS) big2.o
|
||||||
|
|
||||||
parser: parser.o
|
parser: parser.o
|
||||||
$(CC) -o parser $(CFLAGS) parser.o
|
$(CC) -o parser -s $(CFLAGS) parser.o
|
||||||
|
|
||||||
|
|
||||||
uint.o: uint.cpp
|
uint.o: uint.cpp
|
||||||
|
@ -42,5 +43,5 @@ clean:
|
||||||
rm -f big
|
rm -f big
|
||||||
rm -f big2
|
rm -f big2
|
||||||
rm -f parser
|
rm -f parser
|
||||||
# on MS Windows can automatically be added suffixes .exe to the names of output programs
|
# on MS Windows suffixes .exe will be automatically added
|
||||||
rm -f *.exe
|
rm -f *.exe
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CC = g++
|
CC = clang++
|
||||||
o = main.o uinttest.o
|
o = main.o uinttest.o
|
||||||
CFLAGS = -Wall -O2 -s
|
CFLAGS = -Wall -O2
|
||||||
ttmath = ..
|
ttmath = ..
|
||||||
name = tests
|
name = tests
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ all: $(name)
|
||||||
|
|
||||||
|
|
||||||
$(name): $(o)
|
$(name): $(o)
|
||||||
$(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o)
|
$(CC) -o $(name) -s $(CFLAGS) -I$(ttmath) $(o)
|
||||||
|
|
||||||
|
|
||||||
main.o: main.cpp uinttest.h
|
main.o: main.cpp uinttest.h
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
#CC = g++6
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I.. -Wl,-rpath=/usr/local/lib/gcc6
|
||||||
|
|
||||||
|
CC = clang++
|
||||||
|
CFLAGS = -Wall -pedantic -O3 -s -I..
|
||||||
|
#CFLAGS = -Wall -pedantic -O3 -DTTMATH_NOASM -s -I..
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.SUFFIXES: .cpp .o
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
all: big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
big_64_64: main.cpp
|
||||||
|
$(CC) -o big_64_64 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=64 main.cpp
|
||||||
|
|
||||||
|
big_64_128: main.cpp
|
||||||
|
$(CC) -o big_64_128 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=128 main.cpp
|
||||||
|
|
||||||
|
big_64_192: main.cpp
|
||||||
|
$(CC) -o big_64_192 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=192 main.cpp
|
||||||
|
|
||||||
|
big_64_256: main.cpp
|
||||||
|
$(CC) -o big_64_256 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=256 main.cpp
|
||||||
|
|
||||||
|
big_64_512: main.cpp
|
||||||
|
$(CC) -o big_64_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||||
|
|
||||||
|
big_64_1024: main.cpp
|
||||||
|
$(CC) -o big_64_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||||
|
|
||||||
|
big_64_2048: main.cpp
|
||||||
|
$(CC) -o big_64_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||||
|
|
||||||
|
big_64_4096: main.cpp
|
||||||
|
$(CC) -o big_64_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=64 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||||
|
|
||||||
|
big_128_512: main.cpp
|
||||||
|
$(CC) -o big_128_512 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=512 main.cpp
|
||||||
|
|
||||||
|
big_256_1024: main.cpp
|
||||||
|
$(CC) -o big_256_1024 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=256 -DTTMATH_TEST_BIG_MANTISSA=1024 main.cpp
|
||||||
|
|
||||||
|
big_512_2048: main.cpp
|
||||||
|
$(CC) -o big_512_2048 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=512 -DTTMATH_TEST_BIG_MANTISSA=2048 main.cpp
|
||||||
|
|
||||||
|
big_128_4096: main.cpp
|
||||||
|
$(CC) -o big_128_4096 -s $(CFLAGS) -DTTMATH_TEST_BIG_EXPONENT=128 -DTTMATH_TEST_BIG_MANTISSA=4096 main.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
test: all
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=64"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_64 "foo" | tee big_64_64.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=128"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_128 "foo" | tee big_64_128.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=192"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_192 "foo" | tee big_64_192.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=256"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_256 "foo" | tee big_64_256.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=512"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_512 "foo" | tee big_64_512.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=1024"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_1024 "foo" | tee big_64_1024.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=2048"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_2048 "foo" | tee big_64_2048.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=64 and mantissa=4096"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_64_4096 "foo" | tee big_64_4096.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=128 and mantissa=512"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_128_512 "foo" | tee big_128_512.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=128 and mantissa=4096"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_128_4096 "foo" | tee big_128_4096.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=256 and mantissa=1024"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_256_1024 "foo" | tee big_256_1024.out
|
||||||
|
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
@echo "making tests for exponent=512 and mantissa=2048"
|
||||||
|
@echo "****************************************************************************"
|
||||||
|
cat tests.txt | xargs -S 4096 -I foo ./big_512_2048 "foo" | tee big_512_2048.out
|
||||||
|
|
||||||
|
./check_files.sh
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.out
|
||||||
|
rm -f big_64_64 big_64_128 big_64_192 big_64_256 big_64_512 big_64_1024 big_64_2048 big_64_4096 big_128_512 big_256_1024 big_512_2048 big_128_4096
|
||||||
|
# on MS Windows suffixes .exe will be automatically added
|
||||||
|
rm -f *.exe
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
was_error=0
|
||||||
|
|
||||||
|
for expected in *.expected ; do
|
||||||
|
|
||||||
|
out=`basename $expected .expected`.out
|
||||||
|
|
||||||
|
if [ -f $out ] ; then
|
||||||
|
diff -u $out $expected
|
||||||
|
|
||||||
|
if [ `diff -u $out $expected | wc -l` -ne 0 ] ; then
|
||||||
|
was_error=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "there is no file: $out"
|
||||||
|
was_error=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
if [ $was_error -eq 0 ] ; then
|
||||||
|
echo "****************************************************************************"
|
||||||
|
echo " congratulations: all tests passed successfully"
|
||||||
|
echo "****************************************************************************"
|
||||||
|
else
|
||||||
|
echo "****************************************************************************"
|
||||||
|
echo " error: not all tests passed successfully"
|
||||||
|
echo "****************************************************************************"
|
||||||
|
fi
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include <ttmath/ttmath.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
typedef ttmath::Big<TTMATH_BITS(TTMATH_TEST_BIG_EXPONENT), TTMATH_BITS(TTMATH_TEST_BIG_MANTISSA)> MyBig;
|
||||||
|
ttmath::Parser<MyBig> parser;
|
||||||
|
std::string all_input;
|
||||||
|
|
||||||
|
for(int i=1 ; i<argc ; ++i)
|
||||||
|
{
|
||||||
|
if( i > 1 )
|
||||||
|
all_input += ' ';
|
||||||
|
|
||||||
|
all_input += argv[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << all_input << " = ";
|
||||||
|
ttmath::ErrorCode err = parser.Parse(all_input);
|
||||||
|
|
||||||
|
if( err == ttmath::err_ok )
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i < parser.stack.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( i > 0 )
|
||||||
|
std::cout << " ; ";
|
||||||
|
|
||||||
|
std::cout << parser.stack[i].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "error: " << static_cast<int>(err) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
150
ttmath/ttmath.h
150
ttmath/ttmath.h
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2012, Tomasz Sowa
|
* Copyright (c) 2006-2017, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -79,10 +79,12 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this function skips the fraction from x
|
this function skips the fraction from x
|
||||||
e.g 2.2 = 2
|
|
||||||
2.7 = 2
|
samples
|
||||||
-2.2 = 2
|
- 2.2 = 2
|
||||||
-2.7 = 2
|
- 2.7 = 2
|
||||||
|
- -2.2 = 2
|
||||||
|
- -2.7 = 2
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType SkipFraction(const ValueType & x)
|
ValueType SkipFraction(const ValueType & x)
|
||||||
|
@ -96,10 +98,12 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this function rounds to the nearest integer value
|
this function rounds to the nearest integer value
|
||||||
e.g 2.2 = 2
|
|
||||||
2.7 = 3
|
samples
|
||||||
-2.2 = -2
|
- 2.2 = 2
|
||||||
-2.7 = -3
|
- 2.7 = 3
|
||||||
|
- -2.2 = -2
|
||||||
|
- -2.7 = -3
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Round(const ValueType & x, ErrorCode * err = 0)
|
ValueType Round(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
@ -127,12 +131,12 @@ namespace ttmath
|
||||||
this function returns a value representing the smallest integer
|
this function returns a value representing the smallest integer
|
||||||
that is greater than or equal to x
|
that is greater than or equal to x
|
||||||
|
|
||||||
Ceil(-3.7) = -3
|
- Ceil(-3.7) = -3
|
||||||
Ceil(-3.1) = -3
|
- Ceil(-3.1) = -3
|
||||||
Ceil(-3.0) = -3
|
- Ceil(-3.0) = -3
|
||||||
Ceil(4.0) = 4
|
- Ceil(4.0) = 4
|
||||||
Ceil(4.2) = 5
|
- Ceil(4.2) = 5
|
||||||
Ceil(4.8) = 5
|
- Ceil(4.8) = 5
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
|
ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
@ -174,12 +178,12 @@ namespace ttmath
|
||||||
this function returns a value representing the largest integer
|
this function returns a value representing the largest integer
|
||||||
that is less than or equal to x
|
that is less than or equal to x
|
||||||
|
|
||||||
Floor(-3.6) = -4
|
- Floor(-3.6) = -4
|
||||||
Floor(-3.1) = -4
|
- Floor(-3.1) = -4
|
||||||
Floor(-3) = -3
|
- Floor(-3) = -3
|
||||||
Floor(2) = 2
|
- Floor(2) = 2
|
||||||
Floor(2.3) = 2
|
- Floor(2.3) = 2
|
||||||
Floor(2.8) = 2
|
- Floor(2.8) = 2
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
|
ValueType Floor(const ValueType & x, ErrorCode * err = 0)
|
||||||
|
@ -346,6 +350,9 @@ namespace ttmath
|
||||||
/*
|
/*
|
||||||
this namespace consists of auxiliary functions
|
this namespace consists of auxiliary functions
|
||||||
(something like 'private' in a class)
|
(something like 'private' in a class)
|
||||||
|
|
||||||
|
this is excluded from doxygen documentation
|
||||||
|
(option EXCLUDE_SYMBOLS in doxygen.cfg)
|
||||||
*/
|
*/
|
||||||
namespace auxiliaryfunctions
|
namespace auxiliaryfunctions
|
||||||
{
|
{
|
||||||
|
@ -866,7 +873,8 @@ namespace ttmath
|
||||||
if( err )
|
if( err )
|
||||||
*err = err_improper_argument;
|
*err = err_improper_argument;
|
||||||
|
|
||||||
return result; // NaN is set by default
|
result.SetZeroNan();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( x.IsSign() )
|
if( x.IsSign() )
|
||||||
|
@ -1611,15 +1619,16 @@ namespace ttmath
|
||||||
minutes and seconds must be greater than or equal zero
|
minutes and seconds must be greater than or equal zero
|
||||||
|
|
||||||
result:
|
result:
|
||||||
if d>=0 : result= d + ((s/60)+m)/60
|
- if d>=0 : result= d + ((s/60)+m)/60
|
||||||
if d<0 : result= d - ((s/60)+m)/60
|
- if d<0 : result= d - ((s/60)+m)/60
|
||||||
|
|
||||||
((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because
|
((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because
|
||||||
there's only one division)
|
there's only one division)
|
||||||
|
|
||||||
for example:
|
samples:
|
||||||
DegToDeg(10, 30, 0) = 10.5
|
|
||||||
DegToDeg(10, 24, 35.6)=10.4098(8)
|
- DegToDeg(10, 30, 0) = 10.5
|
||||||
|
- DegToDeg(10, 24, 35.6)=10.4098(8)
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s,
|
ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s,
|
||||||
|
@ -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....)
|
index must be integer and not negative <0;1;2;3....)
|
||||||
|
|
||||||
if index==0 the result is one
|
- if index==0 the result is one
|
||||||
if x==0 the result is zero and we assume root(0;0) is not defined
|
- if x==0 the result is zero and we assume root(0;0) is not defined
|
||||||
|
|
||||||
if index is even (2;4;6...) the result is x^(1/index) and x>0
|
- if index is even (2;4;6...) the result is x^(1/index) and x>0
|
||||||
if index is odd (1;2;3;...) the result is either
|
- if index is odd (1;2;3;...) the result is either
|
||||||
-(abs(x)^(1/index)) if x<0 or
|
- -(abs(x)^(1/index)) if x<0, or
|
||||||
x^(1/index)) if x>0
|
- x^(1/index)) if x>0
|
||||||
|
|
||||||
(for index==1 the result is equal x)
|
- for index==1 the result is equal x
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
|
ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
|
||||||
|
@ -2119,8 +2129,10 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
absolute value of x
|
absolute value of x
|
||||||
e.g. -2 = 2
|
|
||||||
2 = 2
|
samples:
|
||||||
|
- -2 = 2
|
||||||
|
- 2 = 2
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Abs(const ValueType & x)
|
ValueType Abs(const ValueType & x)
|
||||||
|
@ -2134,9 +2146,11 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
it returns the sign of the value
|
it returns the sign of the value
|
||||||
e.g. -2 = -1
|
|
||||||
0 = 0
|
samples:
|
||||||
10 = 1
|
- -2 = -1
|
||||||
|
- 0 = 0
|
||||||
|
- 10 = 1
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Sgn(ValueType x)
|
ValueType Sgn(ValueType x)
|
||||||
|
@ -2150,11 +2164,11 @@ namespace ttmath
|
||||||
/*!
|
/*!
|
||||||
the remainder from a division
|
the remainder from a division
|
||||||
|
|
||||||
e.g.
|
samples:
|
||||||
mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6
|
- mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6
|
||||||
mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
|
- mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
|
||||||
mod( 12.6 ; -3) = 0.6
|
- mod( 12.6 ; -3) = 0.6
|
||||||
mod(-12.6 ; -3) = -0.6
|
- mod(-12.6 ; -3) = -0.6
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
|
ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
|
||||||
|
@ -2186,7 +2200,8 @@ namespace ttmath
|
||||||
this function is used to store factorials in a given container
|
this function is used to store factorials in a given container
|
||||||
'more' means how many values should be added at the end
|
'more' means how many values should be added at the end
|
||||||
|
|
||||||
e.g.
|
sample:
|
||||||
|
|
||||||
std::vector<ValueType> fact;
|
std::vector<ValueType> fact;
|
||||||
SetFactorialSequence(fact, 3);
|
SetFactorialSequence(fact, 3);
|
||||||
// now the container has three values: 1 1 2
|
// now the container has three values: 1 1 2
|
||||||
|
@ -2221,7 +2236,8 @@ namespace ttmath
|
||||||
an auxiliary function used to calculate Bernoulli numbers
|
an auxiliary function used to calculate Bernoulli numbers
|
||||||
|
|
||||||
this function returns a sum:
|
this function returns a sum:
|
||||||
sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)} k in [0, m-1] (m k) means binomial coefficient = (m! / (k! * (m-k)!))
|
|
||||||
|
sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)} k in [0, m-1] (m k) means binomial coefficient = (m! / (k! * (m-k)!))
|
||||||
|
|
||||||
you should have sufficient factorials in cgamma.fact
|
you should have sufficient factorials in cgamma.fact
|
||||||
(cgamma.fact should have at least m items)
|
(cgamma.fact should have at least m items)
|
||||||
|
@ -2275,9 +2291,10 @@ namespace ttmath
|
||||||
an auxiliary function used to calculate Bernoulli numbers
|
an auxiliary function used to calculate Bernoulli numbers
|
||||||
start is >= 2
|
start is >= 2
|
||||||
|
|
||||||
we use the recurrence formula:
|
we use the recurrence formula:
|
||||||
B(m) = 1 / (2*(1 - 2^m)) * sum(m)
|
|
||||||
where sum(m) is calculated by SetBernoulliNumbersSum()
|
B(m) = 1 / (2*(1 - 2^m)) * sum(m)
|
||||||
|
where sum(m) is calculated by SetBernoulliNumbersSum()
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
bool SetBernoulliNumbersMore(CGamma<ValueType> & cgamma, uint start, const volatile StopCalculating * stop = 0)
|
bool SetBernoulliNumbersMore(CGamma<ValueType> & cgamma, uint start, const volatile StopCalculating * stop = 0)
|
||||||
|
@ -2330,7 +2347,8 @@ namespace ttmath
|
||||||
returns false if there was a stop signal,
|
returns false if there was a stop signal,
|
||||||
'more' means how many values should be added at the end
|
'more' means how many values should be added at the end
|
||||||
|
|
||||||
e.g.
|
sample:
|
||||||
|
|
||||||
typedef Big<1,2> MyBig;
|
typedef Big<1,2> MyBig;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
SetBernoulliNumbers(cgamma, 3);
|
SetBernoulliNumbers(cgamma, 3);
|
||||||
|
@ -2377,9 +2395,11 @@ namespace ttmath
|
||||||
an auxiliary function used to calculate the Gamma() function
|
an auxiliary function used to calculate the Gamma() function
|
||||||
|
|
||||||
we calculate a sum:
|
we calculate a sum:
|
||||||
|
|
||||||
sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) ) } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ...
|
sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) ) } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ...
|
||||||
B(m) means a mth Bernoulli number
|
|
||||||
the sum starts from m=2, we calculate as long as the value will not change after adding a next part
|
B(m) means a mth Bernoulli number
|
||||||
|
the sum starts from m=2, we calculate as long as the value will not change after adding a next part
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
||||||
|
@ -2440,9 +2460,11 @@ namespace ttmath
|
||||||
an auxiliary function used to calculate the Gamma() function
|
an auxiliary function used to calculate the Gamma() function
|
||||||
|
|
||||||
we calculate a helper function GammaFactorialHigh() by using Stirling's series:
|
we calculate a helper function GammaFactorialHigh() by using Stirling's series:
|
||||||
n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) )
|
|
||||||
where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY)
|
n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) )
|
||||||
and sum(n) is calculated by GammaFactorialHighSum()
|
|
||||||
|
where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY)
|
||||||
|
and sum(n) is calculated by GammaFactorialHighSum()
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
|
||||||
|
@ -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 this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
|
||||||
we use the formula:
|
we use the formula:
|
||||||
gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1)
|
|
||||||
|
gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1)
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & cgamma)
|
ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & cgamma)
|
||||||
|
@ -2545,11 +2568,12 @@ namespace ttmath
|
||||||
|
|
||||||
we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
|
we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
|
||||||
we use a recurrence formula:
|
we use a recurrence formula:
|
||||||
|
|
||||||
gamma(z+1) = z * gamma(z)
|
gamma(z+1) = z * gamma(z)
|
||||||
then: gamma(z) = gamma(z+1) / z
|
then: gamma(z) = gamma(z+1) / z
|
||||||
|
|
||||||
e.g.
|
samples:
|
||||||
gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
|
- gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
|
||||||
*/
|
*/
|
||||||
template<class ValueType>
|
template<class ValueType>
|
||||||
ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
|
ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
|
||||||
|
@ -2640,11 +2664,13 @@ namespace ttmath
|
||||||
|
|
||||||
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma()
|
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma()
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
typedef Big<1,2> MyBig;
|
typedef Big<1,2> MyBig;
|
||||||
MyBig x=234, y=345.53;
|
MyBig x=234, y=345.53;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
std::cout << Gamma(x, cgamma) << std::endl;
|
std::cout << Gamma(x, cgamma) << std::endl;
|
||||||
std::cout << Gamma(y, cgamma) << std::endl;
|
std::cout << Gamma(y, cgamma) << std::endl;
|
||||||
|
|
||||||
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
||||||
and they will be reused in next calls to the function
|
and they will be reused in next calls to the function
|
||||||
|
|
||||||
|
@ -2685,7 +2711,7 @@ namespace ttmath
|
||||||
if( n.IsZero() )
|
if( n.IsZero() )
|
||||||
{
|
{
|
||||||
err_tmp = err_improper_argument;
|
err_tmp = err_improper_argument;
|
||||||
result.SetNan();
|
result.SetZeroNan();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2768,11 +2794,13 @@ namespace ttmath
|
||||||
|
|
||||||
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial()
|
it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial()
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
typedef Big<1,2> MyBig;
|
typedef Big<1,2> MyBig;
|
||||||
MyBig x=234, y=54345;
|
MyBig x=234, y=54345;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
std::cout << Factorial(x, cgamma) << std::endl;
|
std::cout << Factorial(x, cgamma) << std::endl;
|
||||||
std::cout << Factorial(y, cgamma) << std::endl;
|
std::cout << Factorial(y, cgamma) << std::endl;
|
||||||
|
|
||||||
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
|
||||||
and they will be reused in next calls to the function
|
and they will be reused in next calls to the function
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2012, Tomasz Sowa
|
* Copyright (c) 2006-2019, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -66,19 +66,19 @@ class Big
|
||||||
/*
|
/*
|
||||||
value = mantissa * 2^exponent
|
value = mantissa * 2^exponent
|
||||||
|
|
||||||
exponent - an integer value with a sign
|
- exponent - an integer value with a sign
|
||||||
mantissa - an integer value without a sing
|
- mantissa - an integer value without a sing
|
||||||
|
|
||||||
mantissa must be pushed into the left side that is the highest bit from
|
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
|
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:
|
for example:
|
||||||
if we want to store value one (1) into our Big object we must:
|
if we want to store value one (1) into our Big object we must:
|
||||||
set mantissa to 1
|
- set mantissa to 1
|
||||||
set exponent to 0
|
- set exponent to 0
|
||||||
set info to 0
|
- set info to 0
|
||||||
and call method Standardizing()
|
- and call method Standardizing()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,12 +135,12 @@ public:
|
||||||
/*!
|
/*!
|
||||||
returning the string represents the currect type of the library
|
returning the string represents the currect type of the library
|
||||||
we have following types:
|
we have following types:
|
||||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
asm_vc_64 - with asm for VC (64 bit)
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
asm_gcc_64 - with asm for GCC (64 bit)
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
*/
|
*/
|
||||||
static const char * LibTypeStr()
|
static const char * LibTypeStr()
|
||||||
{
|
{
|
||||||
|
@ -392,6 +392,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetPi()
|
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();
|
SetMantissaPi();
|
||||||
info = 0;
|
info = 0;
|
||||||
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
|
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
|
||||||
|
@ -403,6 +405,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void Set05Pi()
|
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();
|
SetMantissaPi();
|
||||||
info = 0;
|
info = 0;
|
||||||
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
|
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
|
||||||
|
@ -414,6 +418,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void Set2Pi()
|
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();
|
SetMantissaPi();
|
||||||
info = 0;
|
info = 0;
|
||||||
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
|
exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
|
||||||
|
@ -669,9 +675,9 @@ public:
|
||||||
this method clears the sign
|
this method clears the sign
|
||||||
(there'll be an absolute value)
|
(there'll be an absolute value)
|
||||||
|
|
||||||
e.g.
|
samples
|
||||||
-1 -> 1
|
- -1 -> 1
|
||||||
2 -> 2
|
- 2 -> 2
|
||||||
*/
|
*/
|
||||||
void Abs()
|
void Abs()
|
||||||
{
|
{
|
||||||
|
@ -681,9 +687,11 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method remains the 'sign' of the value
|
this method remains the 'sign' of the value
|
||||||
e.g. -2 = -1
|
|
||||||
0 = 0
|
samples
|
||||||
10 = 1
|
- -2 = -1
|
||||||
|
- 0 = 0
|
||||||
|
- 10 = 1
|
||||||
*/
|
*/
|
||||||
void Sgn()
|
void Sgn()
|
||||||
{
|
{
|
||||||
|
@ -708,9 +716,9 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method sets the sign
|
this method sets the sign
|
||||||
|
|
||||||
e.g.
|
samples
|
||||||
-1 -> -1
|
- -1 -> -1
|
||||||
2 -> -2
|
- 2 -> -2
|
||||||
|
|
||||||
we do not check whether there is a zero or not, if you're using this method
|
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
|
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
|
this method changes the sign
|
||||||
when there is a value of zero then the sign is not changed
|
when there is a value of zero then the sign is not changed
|
||||||
|
|
||||||
e.g.
|
samples
|
||||||
-1 -> 1
|
- -1 -> 1
|
||||||
2 -> -2
|
- 2 -> -2
|
||||||
*/
|
*/
|
||||||
void ChangeSign()
|
void ChangeSign()
|
||||||
{
|
{
|
||||||
|
@ -750,8 +758,8 @@ private:
|
||||||
this method does the half-to-even rounding (banker's rounding)
|
this method does the half-to-even rounding (banker's rounding)
|
||||||
|
|
||||||
if is_half is:
|
if is_half is:
|
||||||
true - that means the rest was equal the half (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)
|
- 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
|
if the rest was less than a half then don't call this method
|
||||||
(the rounding should does nothing then)
|
(the rounding should does nothing then)
|
||||||
|
@ -922,7 +930,6 @@ public:
|
||||||
uint Add(Big<exp, man> ss2, bool round = true, bool adding = true)
|
uint Add(Big<exp, man> ss2, bool round = true, bool adding = true)
|
||||||
{
|
{
|
||||||
bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
|
bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
|
||||||
Int<exp> exp_offset( exponent );
|
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
|
|
||||||
if( IsNan() || ss2.IsNan() )
|
if( IsNan() || ss2.IsNan() )
|
||||||
|
@ -931,32 +938,41 @@ public:
|
||||||
if( !adding )
|
if( !adding )
|
||||||
ss2.ChangeSign(); // subtracting
|
ss2.ChangeSign(); // subtracting
|
||||||
|
|
||||||
exp_offset.Sub( ss2.exponent );
|
|
||||||
exp_offset.Abs();
|
|
||||||
|
|
||||||
// (1) abs(this) will be >= abs(ss2)
|
// (1) abs(this) will be >= abs(ss2)
|
||||||
if( SmallerWithoutSignThan(ss2) )
|
if( SmallerWithoutSignThan(ss2) )
|
||||||
Swap(ss2);
|
Swap(ss2);
|
||||||
|
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
last_bit_set = rest_zero = do_adding = do_rounding = false;
|
Int<exp> exp_offset( exponent );
|
||||||
rounding_up = (IsSign() == ss2.IsSign());
|
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 )
|
last_bit_set = rest_zero = do_adding = do_rounding = false;
|
||||||
c += AddMantissas(ss2, last_bit_set, rest_zero);
|
rounding_up = (IsSign() == ss2.IsSign());
|
||||||
|
|
||||||
if( !round || !last_bit_set )
|
AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
|
||||||
do_rounding = false;
|
|
||||||
|
|
||||||
if( do_rounding )
|
if( do_adding )
|
||||||
c += RoundHalfToEven(rest_zero, rounding_up);
|
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);
|
return CheckCarry(c);
|
||||||
}
|
}
|
||||||
|
@ -977,13 +993,16 @@ public:
|
||||||
bitwise AND
|
bitwise AND
|
||||||
|
|
||||||
this and ss2 must be >= 0
|
this and ss2 must be >= 0
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - this or ss2 was negative
|
- 2 - this or ss2 was negative
|
||||||
*/
|
*/
|
||||||
uint BitAnd(Big<exp, man> ss2)
|
uint BitAnd(Big<exp, man> ss2)
|
||||||
{
|
{
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
if( IsNan() || ss2.IsNan() )
|
if( IsNan() || ss2.IsNan() )
|
||||||
return CheckCarry(1);
|
return CheckCarry(1);
|
||||||
|
|
||||||
|
@ -1002,20 +1021,20 @@ public:
|
||||||
return 0;
|
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)
|
// abs(this) will be >= abs(ss2)
|
||||||
if( SmallerWithoutSignThan(ss2) )
|
if( SmallerWithoutSignThan(ss2) )
|
||||||
Swap(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
|
// the second value is too small
|
||||||
SetZero();
|
SetZero();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1036,12 +1055,15 @@ public:
|
||||||
|
|
||||||
this and ss2 must be >= 0
|
this and ss2 must be >= 0
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
|
||||||
1 - carry
|
- 0 - ok
|
||||||
2 - this or ss2 was negative
|
- 1 - carry
|
||||||
|
- 2 - this or ss2 was negative
|
||||||
*/
|
*/
|
||||||
uint BitOr(Big<exp, man> ss2)
|
uint BitOr(Big<exp, man> ss2)
|
||||||
{
|
{
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
if( IsNan() || ss2.IsNan() )
|
if( IsNan() || ss2.IsNan() )
|
||||||
return CheckCarry(1);
|
return CheckCarry(1);
|
||||||
|
|
||||||
|
@ -1060,21 +1082,23 @@ public:
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
return 0;
|
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)
|
// abs(this) will be >= abs(ss2)
|
||||||
if( SmallerWithoutSignThan(ss2) )
|
if( SmallerWithoutSignThan(ss2) )
|
||||||
Swap(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
|
// the second value is too small
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||||
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
||||||
|
@ -1091,12 +1115,15 @@ public:
|
||||||
|
|
||||||
this and ss2 must be >= 0
|
this and ss2 must be >= 0
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
|
||||||
1 - carry
|
- 0 - ok
|
||||||
2 - this or ss2 was negative
|
- 1 - carry
|
||||||
|
- 2 - this or ss2 was negative
|
||||||
*/
|
*/
|
||||||
uint BitXor(Big<exp, man> ss2)
|
uint BitXor(Big<exp, man> ss2)
|
||||||
{
|
{
|
||||||
|
uint c = 0;
|
||||||
|
|
||||||
if( IsNan() || ss2.IsNan() )
|
if( IsNan() || ss2.IsNan() )
|
||||||
return CheckCarry(1);
|
return CheckCarry(1);
|
||||||
|
|
||||||
|
@ -1115,21 +1142,23 @@ public:
|
||||||
return 0;
|
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)
|
// abs(this) will be >= abs(ss2)
|
||||||
if( SmallerWithoutSignThan(ss2) )
|
if( SmallerWithoutSignThan(ss2) )
|
||||||
Swap(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
|
// the second value is too small
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||||
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
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
|
call this method only if the highest bit is set - you have to test it beforehand
|
||||||
|
|
||||||
return:
|
return:
|
||||||
true - tab was equal the half (0.5 decimal)
|
- true - tab was equal the half (0.5 decimal)
|
||||||
false - tab was greater than a half (greater than 0.5 decimal)
|
- false - tab was greater than a half (greater than 0.5 decimal)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
bool CheckGreaterOrEqualHalf(uint * tab, uint len)
|
bool CheckGreaterOrEqualHalf(uint * tab, uint len)
|
||||||
|
@ -1361,9 +1390,9 @@ private:
|
||||||
division this = this / ss2
|
division this = this / ss2
|
||||||
|
|
||||||
return value:
|
return value:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry (in a division carry can be as well)
|
- 1 - carry (in a division carry can be as well)
|
||||||
2 - improper argument (ss2 is zero)
|
- 2 - improper argument (ss2 is zero)
|
||||||
*/
|
*/
|
||||||
uint DivRef(const Big<exp, man> & ss2, bool round = true)
|
uint DivRef(const Big<exp, man> & ss2, bool round = true)
|
||||||
{
|
{
|
||||||
|
@ -1434,9 +1463,9 @@ public:
|
||||||
division this = this / ss2
|
division this = this / ss2
|
||||||
|
|
||||||
return value:
|
return value:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry (in a division carry can be as well)
|
- 1 - carry (in a division carry can be as well)
|
||||||
2 - improper argument (ss2 is zero)
|
- 2 - improper argument (ss2 is zero)
|
||||||
*/
|
*/
|
||||||
uint Div(const Big<exp, man> & ss2, bool round = true)
|
uint Div(const Big<exp, man> & ss2, bool round = true)
|
||||||
{
|
{
|
||||||
|
@ -1492,21 +1521,20 @@ private:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the remainder from a division
|
caltulate the remainder from a division
|
||||||
|
|
||||||
e.g.
|
samples
|
||||||
12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6
|
- 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 bacause -12.6 = 3*(-4) + (-0.6)
|
||||||
12.6 mod -3 = 0.6
|
- 12.6 mod -3 = 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)
|
in other words: this(old) = ss2 * q + this(new)
|
||||||
|
|
||||||
return value:
|
return value:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - improper argument (ss2 is zero)
|
- 2 - improper argument (ss2 is zero)
|
||||||
*/
|
*/
|
||||||
uint Mod(const Big<exp, man> & ss2)
|
uint Mod(const Big<exp, man> & ss2)
|
||||||
{
|
{
|
||||||
|
@ -1548,9 +1576,9 @@ public:
|
||||||
binary algorithm (r-to-l)
|
binary algorithm (r-to-l)
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect arguments (0^0)
|
- 2 - incorrect arguments (0^0)
|
||||||
*/
|
*/
|
||||||
template<uint pow_size>
|
template<uint pow_size>
|
||||||
uint Pow(UInt<pow_size> pow)
|
uint Pow(UInt<pow_size> pow)
|
||||||
|
@ -1600,9 +1628,9 @@ public:
|
||||||
p can be negative
|
p can be negative
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect arguments 0^0 or 0^(-something)
|
- 2 - incorrect arguments 0^0 or 0^(-something)
|
||||||
*/
|
*/
|
||||||
template<uint pow_size>
|
template<uint pow_size>
|
||||||
uint Pow(Int<pow_size> pow)
|
uint Pow(Int<pow_size> pow)
|
||||||
|
@ -1640,9 +1668,9 @@ public:
|
||||||
if pow has a fraction the fraction is skipped (not used in calculation)
|
if pow has a fraction the fraction is skipped (not used in calculation)
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect arguments (0^0)
|
- 2 - incorrect arguments (0^0)
|
||||||
*/
|
*/
|
||||||
uint PowUInt(Big<exp, man> pow)
|
uint PowUInt(Big<exp, man> pow)
|
||||||
{
|
{
|
||||||
|
@ -1696,9 +1724,9 @@ public:
|
||||||
pow can be negative
|
pow can be negative
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect arguments 0^0 or 0^(-something)
|
- 2 - incorrect arguments 0^0 or 0^(-something)
|
||||||
*/
|
*/
|
||||||
uint PowInt(const Big<exp, man> & pow)
|
uint PowInt(const Big<exp, man> & pow)
|
||||||
{
|
{
|
||||||
|
@ -1732,9 +1760,9 @@ public:
|
||||||
pow can be negative and with fraction
|
pow can be negative and with fraction
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect argument ('this' <= 0)
|
- 2 - incorrect argument ('this' <= 0)
|
||||||
*/
|
*/
|
||||||
uint PowFrac(const Big<exp, man> & pow)
|
uint PowFrac(const Big<exp, man> & pow)
|
||||||
{
|
{
|
||||||
|
@ -1762,9 +1790,9 @@ public:
|
||||||
pow can be negative and with fraction
|
pow can be negative and with fraction
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect argument ('this' or 'pow')
|
- 2 - incorrect argument ('this' or 'pow')
|
||||||
*/
|
*/
|
||||||
uint Pow(const Big<exp, man> & pow)
|
uint Pow(const Big<exp, man> & pow)
|
||||||
{
|
{
|
||||||
|
@ -1799,9 +1827,10 @@ public:
|
||||||
this function calculates the square root
|
this function calculates the square root
|
||||||
e.g. let this=9 then this.Sqrt() gives 3
|
e.g. let this=9 then this.Sqrt() gives 3
|
||||||
|
|
||||||
return: 0 - ok
|
return:
|
||||||
1 - carry
|
- 0 - ok
|
||||||
2 - improper argument (this<0 or NaN)
|
- 1 - carry
|
||||||
|
- 2 - improper argument (this<0 or NaN)
|
||||||
*/
|
*/
|
||||||
uint Sqrt()
|
uint Sqrt()
|
||||||
{
|
{
|
||||||
|
@ -1924,8 +1953,11 @@ public:
|
||||||
Exponent this = exp(x) = e^x
|
Exponent this = exp(x) = e^x
|
||||||
|
|
||||||
we're using the fact that our value is stored in form of:
|
we're using the fact that our value is stored in form of:
|
||||||
|
|
||||||
x = mantissa * 2^exponent
|
x = mantissa * 2^exponent
|
||||||
|
|
||||||
then
|
then
|
||||||
|
|
||||||
e^x = e^(mantissa* 2^exponent) or
|
e^x = e^(mantissa* 2^exponent) or
|
||||||
e^x = (e^mantissa)^(2^exponent)
|
e^x = (e^mantissa)^(2^exponent)
|
||||||
|
|
||||||
|
@ -2094,17 +2126,20 @@ public:
|
||||||
(a logarithm with the base equal 'e')
|
(a logarithm with the base equal 'e')
|
||||||
|
|
||||||
we're using the fact that our value is stored in form of:
|
we're using the fact that our value is stored in form of:
|
||||||
|
|
||||||
x = mantissa * 2^exponent
|
x = mantissa * 2^exponent
|
||||||
|
|
||||||
then
|
then
|
||||||
|
|
||||||
ln(x) = ln (mantissa * 2^exponent) = ln (mantissa) + (exponent * ln (2))
|
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
|
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
|
is decreasing too fast when 'x' is going to 0
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - overflow (carry)
|
- 1 - overflow (carry)
|
||||||
2 - incorrect argument (x<=0)
|
- 2 - incorrect argument (x<=0)
|
||||||
*/
|
*/
|
||||||
uint Ln(const Big<exp,man> & x)
|
uint Ln(const Big<exp,man> & x)
|
||||||
{
|
{
|
||||||
|
@ -2142,13 +2177,14 @@ public:
|
||||||
Logarithm from 'x' with a 'base'
|
Logarithm from 'x' with a 'base'
|
||||||
|
|
||||||
we're using the formula:
|
we're using the formula:
|
||||||
|
|
||||||
Log(x) with 'base' = ln(x) / ln(base)
|
Log(x) with 'base' = ln(x) / ln(base)
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - overflow
|
- 1 - overflow
|
||||||
2 - incorrect argument (x<=0)
|
- 2 - incorrect argument (x<=0)
|
||||||
3 - incorrect base (a<=0 lub a=1)
|
- 3 - incorrect base (a<=0 or a=1)
|
||||||
*/
|
*/
|
||||||
uint Log(const Big<exp,man> & x, const Big<exp,man> & base)
|
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
|
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':
|
exponent bits, 'E', and the final 52 bits are the fraction 'F':
|
||||||
|
|
||||||
S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||||
0 1 11 12 63
|
0 1 11 12 63
|
||||||
|
|
||||||
The value V represented by the word may be determined as follows:
|
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 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 1, then V=-Infinity
|
||||||
* If E=2047 and F is zero and S is 0, 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 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
|
to represent the binary number created by prefixing F with an implicit
|
||||||
leading 1 and a binary point.
|
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.
|
"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 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 0, then V=0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
@ -2805,6 +2841,7 @@ public:
|
||||||
|
|
||||||
if the value is too big:
|
if the value is too big:
|
||||||
'result' will be +/-infinity (depending on the sign)
|
'result' will be +/-infinity (depending on the sign)
|
||||||
|
|
||||||
if the value is too small:
|
if the value is too small:
|
||||||
'result' will be 0
|
'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',
|
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':
|
and the final 23 bits are the fraction 'F':
|
||||||
|
|
||||||
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
|
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
|
||||||
0 1 8 9 31
|
0 1 8 9 31
|
||||||
|
|
||||||
The value V represented by the word may be determined as follows:
|
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 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 1, then V=-Infinity
|
||||||
* If E=255 and F is zero and S is 0, 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
|
- 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.
|
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 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 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 0, then V=0
|
||||||
*/
|
*/
|
||||||
bool IsInf(float value) const
|
bool IsInf(float value) const
|
||||||
{
|
{
|
||||||
|
// CHECK ME
|
||||||
// need testing on a 64 bit machine
|
// need testing on a 64 bit machine
|
||||||
|
|
||||||
union
|
union
|
||||||
|
@ -2875,6 +2913,7 @@ public:
|
||||||
|
|
||||||
if the value is too big:
|
if the value is too big:
|
||||||
'result' will be +/-infinity (depending on the sign)
|
'result' will be +/-infinity (depending on the sign)
|
||||||
|
|
||||||
if the value is too small:
|
if the value is too small:
|
||||||
'result' will be 0
|
'result' will be 0
|
||||||
*/
|
*/
|
||||||
|
@ -2892,11 +2931,12 @@ public:
|
||||||
this method converts from this class into the 'float'
|
this method converts from this class into the 'float'
|
||||||
|
|
||||||
if the value is too big:
|
if the value is too big:
|
||||||
'result' will be +/-infinity (depending on the sign)
|
- 'result' will be +/-infinity (depending on the sign)
|
||||||
and the method returns 1
|
- and the method returns 1
|
||||||
|
|
||||||
if the value is too small:
|
if the value is too small:
|
||||||
'result' will be 0
|
- 'result' will be 0
|
||||||
and the method returns 1
|
- and the method returns 1
|
||||||
*/
|
*/
|
||||||
uint ToFloat(float & result) const
|
uint ToFloat(float & result) const
|
||||||
{
|
{
|
||||||
|
@ -2929,11 +2969,12 @@ public:
|
||||||
this method converts from this class into the 'double'
|
this method converts from this class into the 'double'
|
||||||
|
|
||||||
if the value is too big:
|
if the value is too big:
|
||||||
'result' will be +/-infinity (depending on the sign)
|
- 'result' will be +/-infinity (depending on the sign)
|
||||||
and the method returns 1
|
- and the method returns 1
|
||||||
|
|
||||||
if the value is too small:
|
if the value is too small:
|
||||||
'result' will be 0
|
- 'result' will be 0
|
||||||
and the method returns 1
|
- and the method returns 1
|
||||||
*/
|
*/
|
||||||
uint ToDouble(double & result) const
|
uint ToDouble(double & result) const
|
||||||
{
|
{
|
||||||
|
@ -3666,11 +3707,10 @@ public:
|
||||||
a method for converting into a string
|
a method for converting into a string
|
||||||
struct Conv is defined in ttmathtypes.h, look there for more information about parameters
|
struct Conv is defined in ttmathtypes.h, look there for more information about parameters
|
||||||
|
|
||||||
output:
|
return value:
|
||||||
return value:
|
- 0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the 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
|
||||||
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)
|
||||||
is somewhere an error in the library)
|
|
||||||
*/
|
*/
|
||||||
uint ToString( std::string & result,
|
uint ToString( std::string & result,
|
||||||
uint base = 10,
|
uint base = 10,
|
||||||
|
@ -4215,10 +4255,12 @@ private:
|
||||||
|
|
||||||
|
|
||||||
if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
|
if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
|
||||||
|
{
|
||||||
// if 'exponent' is <= than '-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
|
// it means that we must cut the whole mantissa
|
||||||
// (there'll not be any of the valid bits)
|
// (there'll not be any of the valid bits)
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// e will be from (-man*TTMATH_BITS_PER_UINT, 0>
|
// e will be from (-man*TTMATH_BITS_PER_UINT, 0>
|
||||||
sint e = -( exponent.ToInt() );
|
sint e = -( exponent.ToInt() );
|
||||||
|
@ -4265,9 +4307,9 @@ private:
|
||||||
a special method used to calculate the new mantissa and exponent
|
a special method used to calculate the new mantissa and exponent
|
||||||
when the 'base' is equal 4, 8 or 16
|
when the 'base' is equal 4, 8 or 16
|
||||||
|
|
||||||
when base is 4 then bits is 2
|
- when base is 4 then bits is 2
|
||||||
when base is 8 then bits is 3
|
- when base is 8 then bits is 3
|
||||||
when base is 16 then bits is 4
|
- when base is 16 then bits is 4
|
||||||
(and the algorithm can be used with a base greater than 16)
|
(and the algorithm can be used with a base greater than 16)
|
||||||
*/
|
*/
|
||||||
template<class string_type>
|
template<class string_type>
|
||||||
|
@ -5151,7 +5193,10 @@ private:
|
||||||
// we could break the parsing somewhere in the middle of the string,
|
// we could break the parsing somewhere in the middle of the string,
|
||||||
// but the result (value) still can be good
|
// but the result (value) still can be good
|
||||||
// we should set a correct value of 'source' now
|
// 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;
|
power_ = power;
|
||||||
c += base_.Pow(power_);
|
c += base_.Pow(power_);
|
||||||
|
@ -5384,8 +5429,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
|
{
|
||||||
// this!=0 and ss2==0
|
// this!=0 and ss2==0
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// we're using the fact that all bits in mantissa are pushed
|
// we're using the fact that all bits in mantissa are pushed
|
||||||
// into the left side -- Standardizing()
|
// into the left side -- Standardizing()
|
||||||
|
@ -5408,16 +5455,22 @@ public:
|
||||||
if( IsZero() )
|
if( IsZero() )
|
||||||
{
|
{
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
|
{
|
||||||
// we've got two zeroes
|
// we've got two zeroes
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// this==0 and ss2!=0
|
// this==0 and ss2!=0
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
|
{
|
||||||
// this!=0 and ss2==0
|
// this!=0 and ss2==0
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// we're using the fact that all bits in mantissa are pushed
|
// we're using the fact that all bits in mantissa are pushed
|
||||||
// into the left side -- Standardizing()
|
// into the left side -- Standardizing()
|
||||||
|
@ -5440,16 +5493,22 @@ public:
|
||||||
if( IsZero() )
|
if( IsZero() )
|
||||||
{
|
{
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
|
{
|
||||||
// we've got two zeroes
|
// we've got two zeroes
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// this==0 and ss2!=0
|
// this==0 and ss2!=0
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ss2.IsZero() )
|
if( ss2.IsZero() )
|
||||||
|
{
|
||||||
// this!=0 and ss2==0
|
// this!=0 and ss2==0
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if( exponent==ss2.exponent && mantissa==ss2.mantissa )
|
if( exponent==ss2.exponent && mantissa==ss2.mantissa )
|
||||||
return true;
|
return true;
|
||||||
|
@ -5461,12 +5520,16 @@ public:
|
||||||
bool operator<(const Big<exp,man> & ss2) const
|
bool operator<(const Big<exp,man> & ss2) const
|
||||||
{
|
{
|
||||||
if( IsSign() && !ss2.IsSign() )
|
if( IsSign() && !ss2.IsSign() )
|
||||||
|
{
|
||||||
// this<0 and ss2>=0
|
// this<0 and ss2>=0
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if( !IsSign() && ss2.IsSign() )
|
if( !IsSign() && ss2.IsSign() )
|
||||||
|
{
|
||||||
// this>=0 and ss2<0
|
// this>=0 and ss2<0
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// both signs are the same
|
// both signs are the same
|
||||||
|
|
||||||
|
@ -5489,12 +5552,16 @@ public:
|
||||||
bool operator>(const Big<exp,man> & ss2) const
|
bool operator>(const Big<exp,man> & ss2) const
|
||||||
{
|
{
|
||||||
if( IsSign() && !ss2.IsSign() )
|
if( IsSign() && !ss2.IsSign() )
|
||||||
|
{
|
||||||
// this<0 and ss2>=0
|
// this<0 and ss2>=0
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if( !IsSign() && ss2.IsSign() )
|
if( !IsSign() && ss2.IsSign() )
|
||||||
|
{
|
||||||
// this>=0 and ss2<0
|
// this>=0 and ss2<0
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// both signs are the same
|
// both signs are the same
|
||||||
|
|
||||||
|
@ -5730,13 +5797,13 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method makes an integer value by skipping any fractions
|
this method makes an integer value by skipping any fractions
|
||||||
|
|
||||||
for example:
|
samples:
|
||||||
10.7 will be 10
|
- 10.7 will be 10
|
||||||
12.1 -- 12
|
- 12.1 -- 12
|
||||||
-20.2 -- 20
|
- -20.2 -- 20
|
||||||
-20.9 -- 20
|
- -20.9 -- 20
|
||||||
-0.7 -- 0
|
- -0.7 -- 0
|
||||||
0.8 -- 0
|
- 0.8 -- 0
|
||||||
*/
|
*/
|
||||||
void SkipFraction()
|
void SkipFraction()
|
||||||
{
|
{
|
||||||
|
@ -5768,9 +5835,9 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method remains only a fraction from the value
|
this method remains only a fraction from the value
|
||||||
|
|
||||||
for example:
|
samples:
|
||||||
30.56 will be 0.56
|
- 30.56 will be 0.56
|
||||||
-12.67 -- -0.67
|
- -12.67 will be -0.67
|
||||||
*/
|
*/
|
||||||
void RemainFraction()
|
void RemainFraction()
|
||||||
{
|
{
|
||||||
|
@ -5811,7 +5878,7 @@ public:
|
||||||
this method returns true if the value is integer
|
this method returns true if the value is integer
|
||||||
(there is no a fraction)
|
(there is no a fraction)
|
||||||
|
|
||||||
(we don't check nan)
|
(we don't check NaN)
|
||||||
*/
|
*/
|
||||||
bool IsInteger() const
|
bool IsInteger() const
|
||||||
{
|
{
|
||||||
|
@ -5853,12 +5920,11 @@ public:
|
||||||
this method rounds to the nearest integer value
|
this method rounds to the nearest integer value
|
||||||
(it returns a carry if it was)
|
(it returns a carry if it was)
|
||||||
|
|
||||||
for example:
|
samples:
|
||||||
2.3 = 2
|
- 2.3 = 2
|
||||||
2.8 = 3
|
- 2.8 = 3
|
||||||
|
- -2.3 = -2
|
||||||
-2.3 = -2
|
- -2.8 = 3
|
||||||
-2.8 = 3
|
|
||||||
*/
|
*/
|
||||||
uint Round()
|
uint Round()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2011, Tomasz Sowa
|
* Copyright (c) 2006-2017, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -55,8 +55,8 @@ namespace ttmath
|
||||||
\brief Int implements a big integer value with a sign
|
\brief Int implements a big integer value with a sign
|
||||||
|
|
||||||
value_size - how many bytes specify our value
|
value_size - how many bytes specify our value
|
||||||
on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
|
- on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
|
||||||
on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
|
- on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
|
||||||
value_size = 1,2,3,4,5,6....
|
value_size = 1,2,3,4,5,6....
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
|
@ -131,8 +131,9 @@ public:
|
||||||
/*!
|
/*!
|
||||||
this method sets the sign
|
this method sets the sign
|
||||||
|
|
||||||
e.g. 1 -> -1
|
samples
|
||||||
-2 -> -2
|
- 1 -> -1
|
||||||
|
- -2 -> -2
|
||||||
|
|
||||||
from a positive value we make a negative value,
|
from a positive value we make a negative value,
|
||||||
if the value is negative we do nothing
|
if the value is negative we do nothing
|
||||||
|
@ -290,10 +291,10 @@ public:
|
||||||
|
|
||||||
this = p1(=this) - p2
|
this = p1(=this) - p2
|
||||||
|
|
||||||
when p1>=0 i p2>=0 carry will never be set
|
- when p1>=0 i p2>=0 carry will never be set
|
||||||
when p1<0 i p2<0 carry will never be set
|
- when p1<0 i p2<0 carry will never be set
|
||||||
when p1>=0 i p2<0 carry is set when the highest bit of value is set
|
- when p1>=0 i p2<0 carry is set when the highest bit of value is set
|
||||||
when p1<0 i p2>=0 carry is set when the highest bit of value is clear
|
- when p1<0 i p2>=0 carry is set when the highest bit of value is clear
|
||||||
*/
|
*/
|
||||||
uint Sub(const Int<value_size> & ss2)
|
uint Sub(const Int<value_size> & ss2)
|
||||||
{
|
{
|
||||||
|
@ -465,14 +466,14 @@ public:
|
||||||
/*!
|
/*!
|
||||||
division this = this / ss2
|
division this = this / ss2
|
||||||
returned values:
|
returned values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
|
|
||||||
for example: (result means 'this')
|
for example: (result means 'this')
|
||||||
20 / 3 --> result: 6 remainder: 2
|
- 20 / 3 --> result: 6 remainder: 2
|
||||||
-20 / 3 --> result: -6 remainder: -2
|
- -20 / 3 --> result: -6 remainder: -2
|
||||||
20 / -3 --> result: -6 remainder: 2
|
- 20 / -3 --> result: -6 remainder: 2
|
||||||
-20 / -3 --> result: 6 remainder: -2
|
- -20 / -3 --> result: 6 remainder: -2
|
||||||
|
|
||||||
in other words: this(old) = ss2 * this(new)(result) + remainder
|
in other words: this(old) = ss2 * this(new)(result) + remainder
|
||||||
*/
|
*/
|
||||||
|
@ -509,14 +510,14 @@ public:
|
||||||
/*!
|
/*!
|
||||||
division this = this / ss2 (ss2 is int)
|
division this = this / ss2 (ss2 is int)
|
||||||
returned values:
|
returned values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
|
|
||||||
for example: (result means 'this')
|
for example: (result means 'this')
|
||||||
20 / 3 --> result: 6 remainder: 2
|
- 20 / 3 --> result: 6 remainder: 2
|
||||||
-20 / 3 --> result: -6 remainder: -2
|
- -20 / 3 --> result: -6 remainder: -2
|
||||||
20 / -3 --> result: -6 remainder: 2
|
- 20 / -3 --> result: -6 remainder: 2
|
||||||
-20 / -3 --> result: 6 remainder: -2
|
- -20 / -3 --> result: 6 remainder: -2
|
||||||
|
|
||||||
in other words: this(old) = ss2 * this(new)(result) + remainder
|
in other words: this(old) = ss2 * this(new)(result) + remainder
|
||||||
*/
|
*/
|
||||||
|
@ -600,9 +601,9 @@ public:
|
||||||
power this = this ^ pow
|
power this = this ^ pow
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect arguments 0^0 or 0^(-something)
|
- 2 - incorrect arguments 0^0 or 0^(-something)
|
||||||
*/
|
*/
|
||||||
uint Pow(Int<value_size> pow)
|
uint Pow(Int<value_size> pow)
|
||||||
{
|
{
|
||||||
|
@ -812,7 +813,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
a copy constructor
|
a copy constructor
|
||||||
*/
|
*/
|
||||||
Int(const Int<value_size> & u)
|
Int(const Int<value_size> & u) : UInt<value_size>()
|
||||||
{
|
{
|
||||||
FromInt(u);
|
FromInt(u);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -171,10 +171,10 @@ static void SkipWhiteCharacters(const char_type * & c)
|
||||||
this static method converts one character into its value
|
this static method converts one character into its value
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
1 -> 1
|
- 1 -> 1
|
||||||
8 -> 8
|
- 8 -> 8
|
||||||
A -> 10
|
- A -> 10
|
||||||
f -> 15
|
- f -> 15
|
||||||
|
|
||||||
this method don't check whether c is correct or not
|
this method don't check whether c is correct or not
|
||||||
*/
|
*/
|
||||||
|
@ -195,9 +195,9 @@ return c-'A'+10;
|
||||||
(if there can't be a correct value it returns -1)
|
(if there can't be a correct value it returns -1)
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
c=2, base=10 -> function returns 2
|
- c=2, base=10 -> function returns 2
|
||||||
c=A, base=10 -> function returns -1
|
- c=A, base=10 -> function returns -1
|
||||||
c=A, base=16 -> function returns 10
|
- c=A, base=16 -> function returns 10
|
||||||
*/
|
*/
|
||||||
static sint CharToDigit(uint c, uint base)
|
static sint CharToDigit(uint c, uint base)
|
||||||
{
|
{
|
||||||
|
@ -228,10 +228,10 @@ return sint(c);
|
||||||
(we don't have to get a base)
|
(we don't have to get a base)
|
||||||
|
|
||||||
for example:
|
for example:
|
||||||
1 -> 1
|
- 1 -> 1
|
||||||
8 -> 8
|
- 8 -> 8
|
||||||
10 -> A
|
- 10 -> A
|
||||||
15 -> F
|
- 15 -> F
|
||||||
*/
|
*/
|
||||||
static uint DigitToChar(uint digit)
|
static uint DigitToChar(uint digit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Mathematical Library
|
* This file is a part of TTMath Mathematical Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
* Copyright (c) 2006-2017, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -81,7 +81,7 @@ public:
|
||||||
// (if there's a variable this 'param' is ignored)
|
// (if there's a variable this 'param' is ignored)
|
||||||
int param;
|
int param;
|
||||||
|
|
||||||
Item() {}
|
Item() { param = 0; }
|
||||||
Item(const std::string & v, int p) : value(v), param(p) {}
|
Item(const std::string & v, int p) : value(v), param(p) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -484,7 +484,7 @@ public:
|
||||||
|
|
||||||
if( i == table.end() )
|
if( i == table.end() )
|
||||||
{
|
{
|
||||||
value.empty();
|
value.clear();
|
||||||
*param = 0;
|
*param = 0;
|
||||||
return err_unknown_object;
|
return err_unknown_object;
|
||||||
}
|
}
|
||||||
|
@ -723,14 +723,17 @@ public:
|
||||||
|
|
||||||
in multithreaded environment you can provide an object of this class to
|
in multithreaded environment you can provide an object of this class to
|
||||||
the Gamma() or Factorial() function, e.g;
|
the Gamma() or Factorial() function, e.g;
|
||||||
|
|
||||||
typedef Big<1, 3> MyBig;
|
typedef Big<1, 3> MyBig;
|
||||||
MyBig x = 123456;
|
MyBig x = 123456;
|
||||||
CGamma<MyBig> cgamma;
|
CGamma<MyBig> cgamma;
|
||||||
std::cout << Gamma(x, cgamma);
|
std::cout << Gamma(x, cgamma);
|
||||||
|
|
||||||
each thread should have its own CGamma<> object
|
each thread should have its own CGamma<> object
|
||||||
|
|
||||||
in a single-thread environment a CGamma<> object is a static variable
|
in a single-thread environment a CGamma<> object is a static variable
|
||||||
in a second version of Gamma() and you don't have to explicitly use it, e.g.
|
and you don't have to explicitly use it, e.g.
|
||||||
|
|
||||||
typedef Big<1, 3> MyBig;
|
typedef Big<1, 3> MyBig;
|
||||||
MyBig x = 123456;
|
MyBig x = 123456;
|
||||||
std::cout << Gamma(x);
|
std::cout << Gamma(x);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -59,24 +59,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
this is a simple skeleton of a program in multithreads environment:
|
|
||||||
|
|
||||||
#define TTMATH_MULTITHREADS
|
|
||||||
#include<ttmath/ttmath.h>
|
|
||||||
|
|
||||||
TTMATH_MULTITHREADS_HELPER
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
|
|
||||||
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
|
||||||
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -186,12 +168,32 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
objects of this class are used to synchronize
|
\brief objects of this class are used to synchronize
|
||||||
|
|
||||||
|
this is a simple skeleton of a program in multithreads environment:
|
||||||
|
|
||||||
|
#define TTMATH_MULTITHREADS
|
||||||
|
#include<ttmath/ttmath.h>
|
||||||
|
|
||||||
|
TTMATH_MULTITHREADS_HELPER
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
|
||||||
|
make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
|
||||||
|
use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
|
||||||
*/
|
*/
|
||||||
class ThreadLock
|
class ThreadLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
lock the current thread
|
||||||
|
|
||||||
|
it uses a global mutex created by TTMATH_MULTITHREADS_HELPER macro
|
||||||
|
*/
|
||||||
bool Lock()
|
bool Lock()
|
||||||
{
|
{
|
||||||
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
if( pthread_mutex_lock(&ttmath_mutex) != 0 )
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2012, Tomasz Sowa
|
* Copyright (c) 2006-2019, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -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
|
TTMATH_PRERELEASE_VER is either zero or one
|
||||||
zero means that this is the release version of the library
|
zero means that this is the release version of the library
|
||||||
(one means something like beta)
|
(one means something like beta)
|
||||||
*/
|
|
||||||
#define TTMATH_MAJOR_VER 0
|
|
||||||
#define TTMATH_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
|
#else
|
||||||
|
|
||||||
/*!
|
|
||||||
on 64bit platforms one word (uint, sint) will be equal 64bits
|
|
||||||
*/
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
/* in VC 'long' type has 32 bits, __int64 is VC extension */
|
||||||
typedef unsigned __int64 uint;
|
typedef unsigned __int64 uint;
|
||||||
typedef signed __int64 sint;
|
typedef signed __int64 sint;
|
||||||
#else
|
#else
|
||||||
typedef unsigned long uint;
|
/*!
|
||||||
typedef signed long sint;
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
|
*/
|
||||||
|
typedef uint64_t uint;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
on 64bit platforms one word (uint, sint) will be equal 64bits
|
||||||
|
*/
|
||||||
|
typedef int64_t sint;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -317,12 +346,12 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
lib type codes:
|
lib type codes:
|
||||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
asm_vc_64 - with asm for VC (64 bit)
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
asm_gcc_64 - with asm for GCC (64 bit)
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
*/
|
*/
|
||||||
enum LibTypeCode
|
enum LibTypeCode
|
||||||
{
|
{
|
||||||
|
@ -366,7 +395,8 @@ namespace ttmath
|
||||||
err_unknown_object,
|
err_unknown_object,
|
||||||
err_still_calculating,
|
err_still_calculating,
|
||||||
err_in_short_form_used_function,
|
err_in_short_form_used_function,
|
||||||
err_percent_from
|
err_percent_from,
|
||||||
|
err_assignment_requires_variable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -407,10 +437,11 @@ namespace ttmath
|
||||||
default: true
|
default: true
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
Conv c;
|
|
||||||
c.base_round = false;
|
Conv c;
|
||||||
Big<1, 1> a = "0.1"; // decimal input
|
c.base_round = false;
|
||||||
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
|
Big<1, 1> a = "0.1"; // decimal input
|
||||||
|
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
|
||||||
*/
|
*/
|
||||||
bool base_round;
|
bool base_round;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2011, Tomasz Sowa
|
* Copyright (c) 2006-2017, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -65,8 +65,8 @@ namespace ttmath
|
||||||
\brief UInt implements a big integer value without a sign
|
\brief UInt implements a big integer value without a sign
|
||||||
|
|
||||||
value_size - how many bytes specify our value
|
value_size - how many bytes specify our value
|
||||||
on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
|
- on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
|
||||||
on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
|
- on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
|
||||||
value_size = 1,2,3,4,5,6....
|
value_size = 1,2,3,4,5,6....
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
|
@ -637,13 +637,13 @@ public:
|
||||||
this method looks for the highest set bit
|
this method looks for the highest set bit
|
||||||
|
|
||||||
result:
|
result:
|
||||||
if 'this' is not zero:
|
- if 'this' is not zero:
|
||||||
return value - true
|
return value - true,
|
||||||
'table_id' - the index of a word <0..value_size-1>
|
'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)
|
'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
|
||||||
|
|
||||||
if 'this' is zero:
|
- if 'this' is zero:
|
||||||
return value - false
|
return value - false,
|
||||||
both 'table_id' and 'index' are zero
|
both 'table_id' and 'index' are zero
|
||||||
*/
|
*/
|
||||||
bool FindLeadingBit(uint & table_id, uint & index) const
|
bool FindLeadingBit(uint & table_id, uint & index) const
|
||||||
|
@ -669,13 +669,13 @@ public:
|
||||||
this method looks for the smallest set bit
|
this method looks for the smallest set bit
|
||||||
|
|
||||||
result:
|
result:
|
||||||
if 'this' is not zero:
|
- if 'this' is not zero:
|
||||||
return value - true
|
return value - true,
|
||||||
'table_id' - the index of a word <0..value_size-1>
|
'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)
|
'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
|
||||||
|
|
||||||
if 'this' is zero:
|
- if 'this' is zero:
|
||||||
return value - false
|
return value - false,
|
||||||
both 'table_id' and 'index' are zero
|
both 'table_id' and 'index' are zero
|
||||||
*/
|
*/
|
||||||
bool FindLowestBit(uint & table_id, uint & index) const
|
bool FindLowestBit(uint & table_id, uint & index) const
|
||||||
|
@ -955,17 +955,20 @@ public:
|
||||||
switch( algorithm )
|
switch( algorithm )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return Mul1Big(ss2, result);
|
Mul1Big(ss2, result);
|
||||||
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
return Mul2Big(ss2, result);
|
Mul2Big(ss2, result);
|
||||||
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
return Mul3Big(ss2, result);
|
Mul3Big(ss2, result);
|
||||||
|
break;
|
||||||
|
|
||||||
case 100:
|
case 100:
|
||||||
default:
|
default:
|
||||||
return MulFastestBig(ss2, result);
|
MulFastestBig(ss2, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,17 +1187,23 @@ public:
|
||||||
|
|
||||||
Karatsuba multiplication:
|
Karatsuba multiplication:
|
||||||
Assume we have:
|
Assume we have:
|
||||||
|
|
||||||
this = x = x1*B^m + x0
|
this = x = x1*B^m + x0
|
||||||
ss2 = y = y1*B^m + y0
|
ss2 = y = y1*B^m + y0
|
||||||
|
|
||||||
where x0 and y0 are less than B^m
|
where x0 and y0 are less than B^m
|
||||||
the product from multiplication we can show as:
|
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
|
x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
|
||||||
where
|
where
|
||||||
|
|
||||||
z2 = x1*y1
|
z2 = x1*y1
|
||||||
z1 = x1*y0 + x0*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:
|
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 /
|
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)
|
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.
|
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
|
//we have the stop point in Mul3Big2() method
|
||||||
#endif
|
#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
|
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
|
#ifdef _MSC_VER
|
||||||
#pragma warning (default : 4717)
|
#pragma warning (default : 4717)
|
||||||
|
@ -1493,7 +1510,10 @@ public:
|
||||||
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
|
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
|
||||||
{
|
{
|
||||||
if( value_size < TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
|
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 x1size = value_size, x2size = value_size;
|
||||||
uint x1start = 0, x2start = 0;
|
uint x1start = 0, x2start = 0;
|
||||||
|
@ -1515,9 +1535,12 @@ public:
|
||||||
uint distancex2 = x2size - x2start;
|
uint distancex2 = x2size - x2start;
|
||||||
|
|
||||||
if( distancex1 < 3 || distancex2 < 3 )
|
if( distancex1 < 3 || distancex2 < 3 )
|
||||||
|
{
|
||||||
// either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
|
// either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
|
||||||
// (this condition in the future can be improved)
|
// (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
|
// Karatsuba multiplication
|
||||||
|
@ -1595,10 +1618,10 @@ public:
|
||||||
division this = this / ss2
|
division this = this / ss2
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
'this' will be the quotient
|
- 'this' will be the quotient
|
||||||
'remainder' - remainder
|
- 'remainder' - remainder
|
||||||
*/
|
*/
|
||||||
uint Div( const UInt<value_size> & divisor,
|
uint Div( const UInt<value_size> & divisor,
|
||||||
UInt<value_size> * remainder = 0,
|
UInt<value_size> * remainder = 0,
|
||||||
|
@ -1629,9 +1652,9 @@ private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
return values:
|
return values:
|
||||||
0 - none has to be done
|
- 0 - none has to be done
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
2 - division should be made
|
- 2 - division should be made
|
||||||
*/
|
*/
|
||||||
uint Div_StandardTest( const UInt<value_size> & v,
|
uint Div_StandardTest( const UInt<value_size> & v,
|
||||||
uint & m, uint & n,
|
uint & m, uint & n,
|
||||||
|
@ -1677,13 +1700,13 @@ private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
'm' - is the index (from 0) of last non-zero word in table ('this')
|
- '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
|
- 'n' - is the index (from 0) of last non-zero word in v.table
|
||||||
1 - v is zero
|
- 1 - v is zero
|
||||||
2 - 'this' is zero
|
- 2 - 'this' is zero
|
||||||
3 - 'this' is smaller than v
|
- 3 - 'this' is smaller than v
|
||||||
4 - 'this' is equal v
|
- 4 - 'this' is equal v
|
||||||
|
|
||||||
if the return value is different than zero the 'm' and 'n' are undefined
|
if the return value is different than zero the 'm' and 'n' are undefined
|
||||||
*/
|
*/
|
||||||
|
@ -1724,7 +1747,7 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the first division algorithm
|
the first division algorithm
|
||||||
radix 2
|
(radix 2)
|
||||||
*/
|
*/
|
||||||
uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
|
uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
|
||||||
{
|
{
|
||||||
|
@ -1747,7 +1770,7 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
the first division algorithm
|
the first division algorithm
|
||||||
radix 2
|
(radix 2)
|
||||||
*/
|
*/
|
||||||
uint Div1(const UInt<value_size> & divisor, UInt<value_size> & remainder)
|
uint Div1(const UInt<value_size> & divisor, UInt<value_size> & remainder)
|
||||||
{
|
{
|
||||||
|
@ -1833,8 +1856,8 @@ public:
|
||||||
the second division algorithm
|
the second division algorithm
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
*/
|
*/
|
||||||
uint Div2(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
|
uint Div2(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
|
||||||
{
|
{
|
||||||
|
@ -1854,8 +1877,8 @@ public:
|
||||||
the second division algorithm
|
the second division algorithm
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
*/
|
*/
|
||||||
uint Div2(const UInt<value_size> & divisor, UInt<value_size> & remainder)
|
uint Div2(const UInt<value_size> & divisor, UInt<value_size> & remainder)
|
||||||
{
|
{
|
||||||
|
@ -1869,8 +1892,8 @@ private:
|
||||||
the second division algorithm
|
the second division algorithm
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
*/
|
*/
|
||||||
uint Div2Ref(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
|
uint Div2Ref(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
|
||||||
{
|
{
|
||||||
|
@ -1901,9 +1924,9 @@ private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
return values:
|
return values:
|
||||||
0 - we've calculated the division
|
- 0 - we've calculated the division
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
2 - we have to still calculate
|
- 2 - we have to still calculate
|
||||||
|
|
||||||
*/
|
*/
|
||||||
uint Div2_Calculate(const UInt<value_size> & divisor, UInt<value_size> * remainder,
|
uint Div2_Calculate(const UInt<value_size> & divisor, UInt<value_size> * remainder,
|
||||||
|
@ -1945,9 +1968,9 @@ private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
return values:
|
return values:
|
||||||
0 - we've calculated the division
|
- 0 - we've calculated the division
|
||||||
1 - division by zero
|
- 1 - division by zero
|
||||||
2 - we have to still calculate
|
- 2 - we have to still calculate
|
||||||
*/
|
*/
|
||||||
uint Div2_FindLeadingBitsAndCheck( const UInt<value_size> & divisor,
|
uint Div2_FindLeadingBitsAndCheck( const UInt<value_size> & divisor,
|
||||||
UInt<value_size> * remainder,
|
UInt<value_size> * remainder,
|
||||||
|
@ -2014,7 +2037,7 @@ private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
return values:
|
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,
|
bool Div2_DivisorGreaterOrEqual( const UInt<value_size> & divisor,
|
||||||
UInt<value_size> * remainder,
|
UInt<value_size> * remainder,
|
||||||
|
@ -2261,8 +2284,8 @@ private:
|
||||||
the bits from 'this' we're moving the same times as 'v')
|
the bits from 'this' we're moving the same times as 'v')
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
d - how many times we've moved
|
- d - how many times we've moved
|
||||||
return - the next-left value from 'this' (that after table[value_size-1])
|
- return - the next-left value from 'this' (that after table[value_size-1])
|
||||||
*/
|
*/
|
||||||
uint Div3_Normalize(UInt<value_size> & v, uint n, uint & d)
|
uint Div3_Normalize(UInt<value_size> & v, uint n, uint & d)
|
||||||
{
|
{
|
||||||
|
@ -2395,9 +2418,9 @@ public:
|
||||||
binary algorithm (r-to-l)
|
binary algorithm (r-to-l)
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
- 0 - ok
|
||||||
1 - carry
|
- 1 - carry
|
||||||
2 - incorrect argument (0^0)
|
- 2 - incorrect argument (0^0)
|
||||||
*/
|
*/
|
||||||
uint Pow(UInt<value_size> pow)
|
uint Pow(UInt<value_size> pow)
|
||||||
{
|
{
|
||||||
|
@ -2475,6 +2498,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets n first bits to value zero
|
this method sets n first bits to value zero
|
||||||
|
|
||||||
|
@ -3310,7 +3334,7 @@ public:
|
||||||
if( negative )
|
if( negative )
|
||||||
result = '-';
|
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 *= TTMATH_BITS_PER_UINT;
|
||||||
digits_d += index + 1;
|
digits_d += index + 1;
|
||||||
digits_d *= ToStringLog2(b);
|
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
|
when compiling Mul3Big2() method
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -39,15 +39,16 @@
|
||||||
#define headerfilettmathuint_noasm
|
#define headerfilettmathuint_noasm
|
||||||
|
|
||||||
|
|
||||||
#ifdef TTMATH_NOASM
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file ttmathuint_noasm.h
|
\file ttmathuint_noasm.h
|
||||||
\brief template class UInt<uint> with methods without any assembler code
|
\brief template class UInt<uint> with methods without any assembler code (used for no-asm version of ttmath)
|
||||||
|
|
||||||
this file is included at the end of ttmathuint.h
|
this file is included at the end of ttmathuint.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef TTMATH_NOASM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ttmath
|
namespace ttmath
|
||||||
{
|
{
|
||||||
|
@ -55,12 +56,12 @@ namespace ttmath
|
||||||
/*!
|
/*!
|
||||||
returning the string represents the currect type of the library
|
returning the string represents the currect type of the library
|
||||||
we have following types:
|
we have following types:
|
||||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
asm_vc_64 - with asm for VC (64 bit)
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
asm_gcc_64 - with asm for GCC (64 bit)
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
const char * UInt<value_size>::LibTypeStr()
|
const char * UInt<value_size>::LibTypeStr()
|
||||||
|
@ -156,12 +157,17 @@ namespace ttmath
|
||||||
and returns a carry (if it was)
|
and returns a carry (if it was)
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
AddInt(2,1)
|
AddInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 + 2;
|
table[1] = 30 + 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -199,17 +205,23 @@ namespace ttmath
|
||||||
x1 - lower word, x2 - higher word
|
x1 - lower word, x2 - higher word
|
||||||
|
|
||||||
for example if we've got value_size equal 4 and:
|
for example if we've got value_size equal 4 and:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4
|
table[1] = 4
|
||||||
table[2] = 5
|
table[2] = 5
|
||||||
table[3] = 6
|
table[3] = 6
|
||||||
|
|
||||||
then let
|
then let
|
||||||
|
|
||||||
x1 = 10
|
x1 = 10
|
||||||
x2 = 20
|
x2 = 20
|
||||||
|
|
||||||
and
|
and
|
||||||
|
|
||||||
index = 1
|
index = 1
|
||||||
|
|
||||||
the result of this method will be:
|
the result of this method will be:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4 + x1 = 14
|
table[1] = 4 + x1 = 14
|
||||||
table[2] = 5 + x2 = 25
|
table[2] = 5 + x2 = 25
|
||||||
|
@ -245,19 +257,20 @@ namespace ttmath
|
||||||
this static method addes one vector to the other
|
this static method addes one vector to the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
|
ss1: ss2: result (output):
|
||||||
|
5 1 5+1
|
||||||
|
4 3 4+3
|
||||||
|
2 7 2+7
|
||||||
|
6 6
|
||||||
|
9 9
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
|
||||||
ss1: ss2: result (output):
|
|
||||||
5 1 5+1
|
|
||||||
4 3 4+3
|
|
||||||
2 7 2+7
|
|
||||||
6 6
|
|
||||||
9 9
|
|
||||||
of course the carry is propagated and will be returned from the last item
|
of course the carry is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
*/
|
*/
|
||||||
|
@ -342,12 +355,17 @@ namespace ttmath
|
||||||
and returns a carry (if it was)
|
and returns a carry (if it was)
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
SubInt(2,1)
|
SubInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 - 2;
|
table[1] = 30 - 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -377,19 +395,19 @@ namespace ttmath
|
||||||
this static method subtractes one vector from the other
|
this static method subtractes one vector from the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
ss1: ss2: result (output):
|
ss1: ss2: result (output):
|
||||||
5 1 5-1
|
5 1 5-1
|
||||||
4 3 4-3
|
4 3 4-3
|
||||||
2 7 2-7
|
2 7 2-7
|
||||||
6 6-1 (the borrow from previous item)
|
6 6-1 (the borrow from previous item)
|
||||||
9 9
|
9 9
|
||||||
return (carry): 0
|
return (carry): 0
|
||||||
of course the carry (borrow) is propagated and will be returned from the last item
|
of course the carry (borrow) is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
|
@ -622,9 +640,11 @@ namespace ttmath
|
||||||
bit is from <0,TTMATH_BITS_PER_UINT-1>
|
bit is from <0,TTMATH_BITS_PER_UINT-1>
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
uint x = 100;
|
|
||||||
uint bit = SetBitInWord(x, 3);
|
uint x = 100;
|
||||||
now: x = 108 and bit = 0
|
uint bit = SetBitInWord(x, 3);
|
||||||
|
|
||||||
|
now: x = 108 and bit = 0
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||||
|
@ -657,10 +677,11 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
multiplication: result_high:result_low = a * b
|
multiplication: result_high:result_low = a * b
|
||||||
result_high - higher word of the result
|
- result_high - higher word of the result
|
||||||
result_low - lower word of the result
|
- result_low - lower word of the result
|
||||||
|
|
||||||
this methos never returns a carry
|
this methos never returns a carry
|
||||||
|
|
||||||
this method is used in the second version of the multiplication algorithms
|
this method is used in the second version of the multiplication algorithms
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -35,16 +35,10 @@
|
||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef headerfilettmathuint_x86
|
#ifndef headerfilettmathuint_x86
|
||||||
#define headerfilettmathuint_x86
|
#define headerfilettmathuint_x86
|
||||||
|
|
||||||
|
|
||||||
#ifndef TTMATH_NOASM
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file ttmathuint_x86.h
|
\file ttmathuint_x86.h
|
||||||
\brief template class UInt<uint> with assembler code for 32bit x86 processors
|
\brief template class UInt<uint> with assembler code for 32bit x86 processors
|
||||||
|
@ -53,6 +47,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TTMATH_NOASM
|
||||||
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief a namespace for the TTMath library
|
\brief a namespace for the TTMath library
|
||||||
|
@ -62,13 +62,14 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returning the string represents the currect type of the library
|
returning the string represents the currect type of the library
|
||||||
|
|
||||||
we have following types:
|
we have following types:
|
||||||
asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
|
||||||
asm_gcc_32 - with asm code designed for GCC (32 bits)
|
- asm_gcc_32 - with asm code designed for GCC (32 bits)
|
||||||
asm_vc_64 - with asm for VC (64 bit)
|
- asm_vc_64 - with asm for VC (64 bit)
|
||||||
asm_gcc_64 - with asm for GCC (64 bit)
|
- asm_gcc_64 - with asm for GCC (64 bit)
|
||||||
no_asm_32 - pure C++ version (32 bit) - without any asm code
|
- no_asm_32 - pure C++ version (32 bit) - without any asm code
|
||||||
no_asm_64 - pure C++ version (64 bit) - without any asm code
|
- no_asm_64 - pure C++ version (64 bit) - without any asm code
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
const char * UInt<value_size>::LibTypeStr()
|
const char * UInt<value_size>::LibTypeStr()
|
||||||
|
@ -210,12 +211,17 @@ namespace ttmath
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
AddInt(2,1)
|
AddInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 + 2;
|
table[1] = 30 + 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -314,17 +320,23 @@ namespace ttmath
|
||||||
x1 - lower word, x2 - higher word
|
x1 - lower word, x2 - higher word
|
||||||
|
|
||||||
for example if we've got value_size equal 4 and:
|
for example if we've got value_size equal 4 and:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4
|
table[1] = 4
|
||||||
table[2] = 5
|
table[2] = 5
|
||||||
table[3] = 6
|
table[3] = 6
|
||||||
|
|
||||||
then let
|
then let
|
||||||
|
|
||||||
x1 = 10
|
x1 = 10
|
||||||
x2 = 20
|
x2 = 20
|
||||||
|
|
||||||
and
|
and
|
||||||
|
|
||||||
index = 1
|
index = 1
|
||||||
|
|
||||||
the result of this method will be:
|
the result of this method will be:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4 + x1 = 14
|
table[1] = 4 + x1 = 14
|
||||||
table[2] = 5 + x2 = 25
|
table[2] = 5 + x2 = 25
|
||||||
|
@ -653,12 +665,17 @@ namespace ttmath
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
SubInt(2,1)
|
SubInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 - 2;
|
table[1] = 30 - 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -1405,9 +1422,10 @@ namespace ttmath
|
||||||
|
|
||||||
bit is from <0,31>
|
bit is from <0,31>
|
||||||
e.g.
|
e.g.
|
||||||
uint x = 100;
|
|
||||||
uint bit = SetBitInWord(x, 3);
|
uint x = 100;
|
||||||
now: x = 108 and bit = 0
|
uint bit = SetBitInWord(x, 3);
|
||||||
|
now: x = 108 and bit = 0
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is a part of TTMath Bignum Library
|
* This file is a part of TTMath Bignum Library
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the 3-Clause BSD Licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -51,6 +51,21 @@
|
||||||
this file is included at the end of ttmathuint.h
|
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__
|
#ifndef __GNUC__
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -195,12 +210,17 @@ namespace ttmath
|
||||||
|
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
AddInt(2,1)
|
AddInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 + 2;
|
table[1] = 30 + 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -265,17 +285,23 @@ namespace ttmath
|
||||||
x1 - lower word, x2 - higher word
|
x1 - lower word, x2 - higher word
|
||||||
|
|
||||||
for example if we've got value_size equal 4 and:
|
for example if we've got value_size equal 4 and:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4
|
table[1] = 4
|
||||||
table[2] = 5
|
table[2] = 5
|
||||||
table[3] = 6
|
table[3] = 6
|
||||||
|
|
||||||
then let
|
then let
|
||||||
|
|
||||||
x1 = 10
|
x1 = 10
|
||||||
x2 = 20
|
x2 = 20
|
||||||
|
|
||||||
and
|
and
|
||||||
|
|
||||||
index = 1
|
index = 1
|
||||||
|
|
||||||
the result of this method will be:
|
the result of this method will be:
|
||||||
|
|
||||||
table[0] = 3
|
table[0] = 3
|
||||||
table[1] = 4 + x1 = 14
|
table[1] = 4 + x1 = 14
|
||||||
table[2] = 5 + x2 = 25
|
table[2] = 5 + x2 = 25
|
||||||
|
@ -341,19 +367,19 @@ namespace ttmath
|
||||||
this static method addes one vector to the other
|
this static method addes one vector to the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
ss1: ss2: result (output):
|
ss1: ss2: result (output):
|
||||||
5 1 5+1
|
5 1 5+1
|
||||||
4 3 4+3
|
4 3 4+3
|
||||||
2 7 2+7
|
2 7 2+7
|
||||||
6 6
|
6 6
|
||||||
9 9
|
9 9
|
||||||
of course the carry is propagated and will be returned from the last item
|
of course the carry is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
*/
|
*/
|
||||||
|
@ -483,12 +509,17 @@ namespace ttmath
|
||||||
***this method is created only on a 64bit platform***
|
***this method is created only on a 64bit platform***
|
||||||
|
|
||||||
if we've got (value_size=3):
|
if we've got (value_size=3):
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30;
|
table[1] = 30;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
|
||||||
and we call:
|
and we call:
|
||||||
|
|
||||||
SubInt(2,1)
|
SubInt(2,1)
|
||||||
|
|
||||||
then it'll be:
|
then it'll be:
|
||||||
|
|
||||||
table[0] = 10;
|
table[0] = 10;
|
||||||
table[1] = 30 - 2;
|
table[1] = 30 - 2;
|
||||||
table[2] = 5;
|
table[2] = 5;
|
||||||
|
@ -545,19 +576,19 @@ namespace ttmath
|
||||||
this static method subtractes one vector from the other
|
this static method subtractes one vector from the other
|
||||||
'ss1' is larger in size or equal to 'ss2'
|
'ss1' is larger in size or equal to 'ss2'
|
||||||
|
|
||||||
ss1 points to the first (larger) vector
|
- ss1 points to the first (larger) vector
|
||||||
ss2 points to the second vector
|
- ss2 points to the second vector
|
||||||
ss1_size - size of the ss1 (and size of the result too)
|
- ss1_size - size of the ss1 (and size of the result too)
|
||||||
ss2_size - size of the ss2
|
- ss2_size - size of the ss2
|
||||||
result - is the result vector (which has size the same as ss1: ss1_size)
|
- result - is the result vector (which has size the same as ss1: ss1_size)
|
||||||
|
|
||||||
Example: ss1_size is 5, ss2_size is 3
|
Example: ss1_size is 5, ss2_size is 3
|
||||||
ss1: ss2: result (output):
|
ss1: ss2: result (output):
|
||||||
5 1 5-1
|
5 1 5-1
|
||||||
4 3 4-3
|
4 3 4-3
|
||||||
2 7 2-7
|
2 7 2-7
|
||||||
6 6-1 (the borrow from previous item)
|
6 6-1 (the borrow from previous item)
|
||||||
9 9
|
9 9
|
||||||
return (carry): 0
|
return (carry): 0
|
||||||
of course the carry (borrow) is propagated and will be returned from the last item
|
of course the carry (borrow) is propagated and will be returned from the last item
|
||||||
(this method is used by the Karatsuba multiplication algorithm)
|
(this method is used by the Karatsuba multiplication algorithm)
|
||||||
|
@ -1029,8 +1060,8 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
multiplication: result_high:result_low = a * b
|
multiplication: result_high:result_low = a * b
|
||||||
result_high - higher word of the result
|
- result_high - higher word of the result
|
||||||
result_low - lower word of the result
|
- result_low - lower word of the result
|
||||||
|
|
||||||
this methos never returns a carry
|
this methos never returns a carry
|
||||||
this method is used in the second version of the multiplication algorithms
|
this method is used in the second version of the multiplication algorithms
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
;
|
;
|
||||||
; This file is a part of TTMath Bignum Library
|
; This file is a part of TTMath Bignum Library
|
||||||
; and is distributed under the (new) BSD licence.
|
; and is distributed under the 3-Clause BSD Licence.
|
||||||
; Author: Christian Kaiser <chk@online.de>
|
; Author: Christian Kaiser <chk@online.de>, Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
;
|
;
|
||||||
|
|
||||||
;
|
;
|
||||||
; Copyright (c) 2009, Christian Kaiser
|
; Copyright (c) 2009-2017, Christian Kaiser, Tomasz Sowa
|
||||||
; All rights reserved.
|
; All rights reserved.
|
||||||
;
|
;
|
||||||
; Redistribution and use in source and binary forms, with or without
|
; Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -41,6 +41,9 @@
|
||||||
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program
|
||||||
;
|
;
|
||||||
|
|
||||||
|
; doxygen info is put to ttmathuint_x86_64.h file
|
||||||
|
|
||||||
|
|
||||||
PUBLIC ttmath_adc_x64
|
PUBLIC ttmath_adc_x64
|
||||||
PUBLIC ttmath_addindexed_x64
|
PUBLIC ttmath_addindexed_x64
|
||||||
PUBLIC ttmath_addindexed2_x64
|
PUBLIC ttmath_addindexed2_x64
|
||||||
|
@ -151,12 +154,12 @@ ttmath_addindexed2_x64 PROC
|
||||||
; rdx = b (value size)
|
; rdx = b (value size)
|
||||||
; r8 = nPos
|
; r8 = nPos
|
||||||
; r9 = nValue1
|
; r9 = nValue1
|
||||||
; [esp+0x28] = nValue2
|
; [rsp+0x28] = nValue2
|
||||||
|
|
||||||
xor rax, rax ; return value
|
xor rax, rax ; return value
|
||||||
mov r11, rcx ; table
|
mov r11, rcx ; table
|
||||||
sub rdx, r8 ; rdx = remaining count of uints
|
sub rdx, r8 ; rdx = remaining count of uints
|
||||||
mov r10, [esp+028h] ; r10 = nValue2
|
mov r10, [rsp+028h] ; r10 = nValue2
|
||||||
|
|
||||||
add qword ptr [r11 + r8 * 8], r9
|
add qword ptr [r11 + r8 * 8], r9
|
||||||
lea r8, [r8+1]
|
lea r8, [r8+1]
|
||||||
|
@ -194,9 +197,9 @@ ttmath_addvector_x64 PROC
|
||||||
; rdx = ss2
|
; rdx = ss2
|
||||||
; r8 = ss1_size
|
; r8 = ss1_size
|
||||||
; r9 = ss2_size
|
; r9 = ss2_size
|
||||||
; [esp+0x28] = result
|
; [rsp+0x28] = result
|
||||||
|
|
||||||
mov r10, [esp+028h]
|
mov r10, [rsp+028h]
|
||||||
sub r8, r9
|
sub r8, r9
|
||||||
xor r11, r11 ; r11=0, cf=0
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
@ -316,9 +319,9 @@ ttmath_subvector_x64 PROC
|
||||||
; rdx = ss2
|
; rdx = ss2
|
||||||
; r8 = ss1_size
|
; r8 = ss1_size
|
||||||
; r9 = ss2_size
|
; r9 = ss2_size
|
||||||
; [esp+0x28] = result
|
; [rsp+0x28] = result
|
||||||
|
|
||||||
mov r10, [esp+028h]
|
mov r10, [rsp+028h]
|
||||||
sub r8, r9
|
sub r8, r9
|
||||||
xor r11, r11 ; r11=0, cf=0
|
xor r11, r11 ; r11=0, cf=0
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
rem make sure this is a proper path to the 64 bit assembler
|
||||||
|
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\ml64.exe" /c ttmathuint_x86_64_msvc.asm
|
||||||
|
rem ml64.exe will produce ttmathuint_x86_64_msvc.obj which should be added (linked) to your project
|
||||||
|
|
||||||
|
rem or you can assemble with debug info
|
||||||
|
rem ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm
|
||||||
|
|
||||||
|
rem be nice, most Windows users just click on the file
|
||||||
|
pause
|
Loading…
Reference in New Issue