Skip to content

Commit

Permalink
fixing inc- and decrement, more unit-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
maitag committed Oct 30, 2020
1 parent 4ec4940 commit 5280bec
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 50 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ var b:BigInt = 7;
trace(a + b); // 10
// increment and decrement
// This works not with haxes operationoverloads yet if argument or result is 0 (because of 'null') !
trace(++a); // 3
trace(a++); // 4
trace( a ); // 5
Expand Down Expand Up @@ -195,8 +194,6 @@ Let me know if something's mising ~^

## Todo

- fixing increment and decrement (++,--) problem with zero value/result
or replace this by .inc() and .dec() functions
- `haxelib run` command for invoking hxp testscripts
- fixing output with leading zeros
- optional exponential notation for decimals
Expand Down
17 changes: 9 additions & 8 deletions benchmarks/CalcPi.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,29 @@ import haxe.Timer;
// calculate Pi with https://en.wikipedia.org/wiki/Machin-like_formula
class CalcPi {
static public function main():Void {
var digits:BigInt = 300;
var digits:Int = 300;
var time = Timer.stamp();
var pi:BigInt = calc(digits);
haxe.Log.trace('Pi = 3.${pi.toString().substr(1)}\n\t\t\t' + Std.int((Timer.stamp() - time)*1000) + "\tms" , #if (haxe_ver >= "4.0.0") null #else {fileName:"",lineNumber:0,className:"",methodName:"",customParams:[]} #end);
}

static public function calc(digits:BigInt):BigInt {
var calcdigits:BigInt = digits + 10;
var calcpi:BigInt = 4 * ( 4 * arctanbyd(5, calcdigits) - arctanbyd(239, calcdigits) );
static public function calc(digits:Int):BigInt {
digits += 10;
var calcpi:BigInt = 4 * ( 4 * arctanbyd(5, digits) - arctanbyd(239, digits) );
calcpi = calcpi / ("10000000000":BigInt);
return(calcpi);
}

static public function arctanbyd(d:Int, digits:BigInt):BigInt {
static public function arctanbyd(d:Int, digits:Int):BigInt {
// calculate arctan(1/d) = 1/d - 1/(3*d^3) + 1/(5*d^5) - 1/(7*d^7) + ...
var arc:BigInt = (10:BigInt).pow(digits) / d;
var part:BigInt = arc;
var n:BigInt = 0;
var dd:Int = -d * d;
while (part != 0) {
n = n + 1;
part = part / (-d * d);
arc = arc + part / (2 * n + 1);
n++;
part = part / dd;
arc = arc + part / (n*2 + 1);
}
return(arc);
}
Expand Down
4 changes: 2 additions & 2 deletions haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"license": "MIT",
"tags": ["math", "arbitrary", "precision", "integer", "bigint"],
"description": "pure haxe implementation for arbitrary-precision integer",
"version": "0.1.1",
"version": "0.1.2",
"classPath": "src/",
"releasenote": "fixing multiplication, adding pi-benchmark",
"releasenote": "fixing multiplication and inc-/decrement, adding pi-benchmark",
"contributors": ["maitag"],
"dependencies": {}
}
81 changes: 47 additions & 34 deletions src/BigInt.hx
Original file line number Diff line number Diff line change
Expand Up @@ -225,31 +225,39 @@ abstract BigInt(LittleIntChunks) from LittleIntChunks {
//@:op(A + B) @:commutative function opAddInt(b:Int):BigInt return _add(this, b);
@:op(A + B) static function opAddInt(a:Int, b:BigInt):BigInt return _add(a, b); // haxe 3.4.4 compatible!

@:op(A++) static function opIncrementAfter(a:BigInt):BigInt {
if (a == null) {
a = BigInt.fromInt(1); // TODO: Can't do "++" for 0 (null can not be changed)
@:op(A++) inline function opIncrementAfter():BigInt {
if (this == null) {
this = LittleIntChunks.createFromLittleInt(1);
return null;
}
var ret = a.copy();
if (a.isNegative) {
if (a == -1) a = null; // TODO: Can't do "++" for 0 (null can not be changed)
else subtractLittle(a, 1, 0);
var ret = copy();
if (isNegative) {
if (length == 1 && get(0) == 1) this = null;
else subtractLittle(this, 1, 0);
}
else addLittle(a, 1, 0);
else addLittle(this, 1, 0);
return ret;
}

@:op(++A) static function opIncrementBefore(a:BigInt):BigInt {
if (a == null) {
a = BigInt.fromInt(1); // TODO: Can't do "++" for 0 (null can not be changed)
return BigInt.fromInt(1);
@:op(++A) inline function opIncrementBefore():BigInt {
if (this == null) {
this = LittleIntChunks.createFromLittleInt(1);
return LittleIntChunks.createFromLittleInt(1);
}
if (a.isNegative) {
if (a == -1) a = null; // TODO: Can't do "++" for 0 (null can not be changed)
subtractLittle(a, 1, 0);
if (isNegative) {
if (length == 1 && get(0) == 1) {
this = null;
return null;
}
else {
subtractLittle(this, 1, 0);
return copy();
}
}
else {
addLittle(this, 1, 0);
return copy();
}
else addLittle(a, 1, 0);
return a.copy();
}

static inline function _add(a:BigInt, b:BigInt):BigInt {
Expand Down Expand Up @@ -303,34 +311,39 @@ abstract BigInt(LittleIntChunks) from LittleIntChunks {
//@:op(A - B) static function opSubtractInt(a:BigInt, b:Int):BigInt return _subtract(a, b);
@:op(A - B) static function opIntSubtract(a:Int, b:BigInt):BigInt return _subtract(a, b);

@:op(A--) static function opDecrementAfter(a:BigInt):BigInt {
if (a == null) {
a = BigInt.fromInt(-1); // TODO: Can't do "--" for 0 (null can not be changed)
@:op(A--) inline function opDecrementAfter():BigInt {
if (this == null) {
this = LittleIntChunks.createFromLittleInt(-1);
return null;
}
var ret = a.copy();
if (a.isNegative) addLittle(a, 1, 0);
var ret = copy();
if (isNegative) addLittle(this, 1, 0);
else {
if (a == 1) a = null; // TODO: Can't do "--" for 0 (null can not be changed)
else subtractLittle(a, 1, 0);
if (length == 1 && get(0) == 1) this = null;
else subtractLittle(this, 1, 0);
}
return ret;
}

@:op(--A) static function opDecrementBefore(a:BigInt):BigInt {
if (a == null) {
a = BigInt.fromInt(-1); // TODO: Can't do "--" for 0 (null can not be changed)
return BigInt.fromInt(-1);
@:op(--A) inline function opDecrementBefore():BigInt {
if (this == null) {
this = LittleIntChunks.createFromLittleInt(-1);
return LittleIntChunks.createFromLittleInt(-1);
}
if (isNegative) {
addLittle(this, 1, 0);
return copy();
}
if (a.isNegative) addLittle(a, 1, 0);
else {
if (a == 1) {
a = null; // TODO: Can't do "--" for 0 (null can not be changed)
if (length == 1 && get(0) == 1) {
this = null;
return null;
}
else subtractLittle(a, 1, 0);
}
return a.copy();
else {
subtractLittle(this, 1, 0);
return copy();
}
}
}

static inline function _subtract(a:BigInt, b:BigInt):BigInt {
Expand Down
23 changes: 20 additions & 3 deletions unit-tests/TestBigInt.hx
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,23 @@ class TestBigInt extends haxe.unit.TestCase
}

public function testIncrement() {
var a:BigInt = "0x 1 1234 5678 abcd efff";
var b:BigInt = a++;
var a:BigInt;
var b:BigInt;
var c:BigInt;
a = "0x 1 1234 5678 abcd efff";
b = a++;
assertTrue( b == ("0x 1 1234 5678 abcd efff" : BigInt) );
assertTrue( a == ("0x 1 1234 5678 abcd f000" : BigInt) );
var c:BigInt = ++a;
c = ++a;
assertTrue( (a == c) && (c == ("0x 1 1234 5678 abcd f001" : BigInt)) );
a = 0; assertTrue(a++ == 0); assertTrue(a == 1);
a =-1; assertTrue(a++ ==-1); assertTrue(a == 0);
a = 0; assertTrue(++a == 1); assertTrue(a == 1);
a =-1; assertTrue(++a == 0); assertTrue(a == 0);
a = 0; assertTrue(a-- == 0); assertTrue(a ==-1);
a = 1; assertTrue(a-- == 1); assertTrue(a == 0);
a = 0; assertTrue(--a ==-1); assertTrue(a ==-1);
a = 1; assertTrue(--a == 0); assertTrue(a == 0);
}

public function testSubtraction() {
Expand Down Expand Up @@ -382,6 +393,12 @@ class TestBigInt extends haxe.unit.TestCase
b = "-333333333333333333333";
c = "-37037037037037037036999999999999999999962962962962962962963";
assertTrue(a * b == c);

// check optimization bug
a = "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000195193276309135075023284912102116616768613765187463511927839869094134045055764247";
b = "10000000000";
c = "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001951932763091350750232849121021166167686137651874635119278398690941340450557642470000000000";
assertTrue(a * b == c);
}

public function testMultiplicationWithInt() {
Expand Down

0 comments on commit 5280bec

Please sign in to comment.