Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BigInteger type #10750

Open
wants to merge 147 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 68 commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
ac9648b
Add BigInteger type
flashultra Jul 7, 2022
d502605
Add BigInt test and allow unit package
flashultra Jul 10, 2022
b6ebec0
Merge branch 'HaxeFoundation:development' into development
flashultra Jul 10, 2022
6aa9204
Add abs,pow,modPow,isProbablePrime,getLowestSetBit,bitLength methods
flashultra Jul 16, 2022
baa9010
Merge branch 'development' of https://github.com/flashultra/haxe into…
flashultra Jul 16, 2022
17a09e6
Add missing tests and counting of trailing zeros
flashultra Jul 16, 2022
60de60d
Run tests for BigInt
flashultra Jul 16, 2022
e2fdb58
Add missing const
flashultra Jul 16, 2022
65bd87c
Fiexes for Int32 ( javascript)
flashultra Jul 17, 2022
2979ee9
More fixes for Int32
flashultra Jul 18, 2022
e0b0218
Add trace for macro crash
flashultra Jul 18, 2022
b63329f
Fix missing ;
flashultra Jul 18, 2022
91688ac
Fix macro test
flashultra Jul 18, 2022
4da8487
Remove macrotest crash
flashultra Jul 18, 2022
99adeca
Fix Int32 (python)
flashultra Jul 19, 2022
f7c405f
More fixes
flashultra Jul 19, 2022
c5dfc60
More fixes for python
flashultra Jul 19, 2022
2dca9df
more fixes
flashultra Jul 19, 2022
4cf361f
Merge branch 'HaxeFoundation:development' into development
flashultra Jul 22, 2022
984a696
Fix for Python target
flashultra Jul 22, 2022
2f45acc
Correct test for mutable bigint
flashultra Jul 22, 2022
39e31fa
Add method to create BigInt from bytes
flashultra Jul 24, 2022
7b5b70b
Add auto convert from String
flashultra Jul 25, 2022
4648790
Add greater common divisor (gcd) of two BigInt values
flashultra Jul 25, 2022
45980ef
Add lcm,min,max,nextprobableprime methods
flashultra Jul 26, 2022
1e8051d
Merge branch 'HaxeFoundation:development' into development
flashultra Jul 26, 2022
4f99754
Add method to create random BigInt
flashultra Jul 26, 2022
d2916d7
Add test for random and small fixes
flashultra Jul 26, 2022
e6fe7c5
More random methods and some fixes
flashultra Jul 28, 2022
ce5378d
Fix pow bug
flashultra Jul 28, 2022
76a883f
Add test for random prime and random in range + prime fix
flashultra Jul 28, 2022
57927b8
Remove trace(..)
flashultra Jul 28, 2022
39252d4
Fix test
flashultra Jul 28, 2022
70fbb33
Fix unsigned compare for randomInRange
flashultra Jul 29, 2022
f2de369
Fix for randomInRange
flashultra Jul 29, 2022
8bf946a
Hope dies last
flashultra Jul 29, 2022
2866088
Fix for JS
flashultra Jul 29, 2022
c26f036
Better check for sign
flashultra Jul 30, 2022
6e8f2d8
Thanks to cbatson
flashultra Aug 1, 2022
bec8abe
Add modInverse method
flashultra Aug 20, 2022
f4d5e6d
Add bitcount(),isPositive,isEven and isOdd methods
flashultra Aug 21, 2022
a0e1598
Add testBit() method
flashultra Aug 21, 2022
3c5c0a2
Add tests for modInverse,isPositive,isEven,isOdd, testBit, bitCount
flashultra Aug 21, 2022
157c0e2
Fix bitcount
flashultra Aug 21, 2022
8bd592c
Try to fix bitCount()
flashultra Aug 21, 2022
3eb46e4
Debug cpp (couldn't repeat)
flashultra Aug 22, 2022
880f710
Fix debug
flashultra Aug 22, 2022
b15c9f0
Debug
flashultra Aug 22, 2022
edbb6d4
[cpp] Fix bitCount()
flashultra Aug 22, 2022
257e751
Add square() and Karatsuba multiplication
flashultra Sep 3, 2022
326d026
Add test for Karatsuba square
flashultra Sep 3, 2022
5273e4c
Merge branch 'HaxeFoundation:development' into development
flashultra Dec 13, 2022
2aebe42
Merge branch 'HaxeFoundation:development' into development
flashultra Dec 13, 2022
197ab84
Merge branch 'HaxeFoundation:development' into development
flashultra Dec 13, 2022
8b65d53
Add divMod and hashCode functions.Auto convert to string
flashultra Jan 18, 2023
b030dec
Fix last commit.
flashultra Jan 18, 2023
21900e6
Fix overflow behaviour
flashultra Jan 18, 2023
39038bf
Add negative base for modInverse
flashultra Jan 26, 2023
de89828
Add OR and AND (bigint) operations
flashultra Jan 31, 2023
786cbec
Fix for negative numbers
flashultra Jan 31, 2023
d1a15f8
Correct OR for bigint
flashultra Jan 31, 2023
3733409
For OR small optimization
flashultra Jan 31, 2023
aec1211
Add XOR and NOT bitwise operators
flashultra Jan 31, 2023
e76288c
Add bit operations and powerOfTwo method
flashultra Feb 26, 2023
c4fe08c
Test bit for negative numbers
flashultra Feb 26, 2023
b877aa9
Use enum abstract for exception. Reformat the code
flashultra Mar 1, 2023
5fa6c53
Add missing tests
flashultra Mar 1, 2023
b7626bc
Temp fix for BigIntException
flashultra Mar 1, 2023
f9417ea
Fix for BigIntExceptions
flashultra Mar 2, 2023
3ab6538
Fix BigIntExceptions test
flashultra Mar 2, 2023
3b87a7e
Fix tests for String conversion
flashultra Mar 2, 2023
1245ce8
Temp fix for flipBit (python)
flashultra Mar 2, 2023
704100c
Add @:noDoc and @:noCompletion .Fix for BigIntException and tests
flashultra Mar 4, 2023
b4faf0a
Change var NEGATIVE_ONE to MINUS_ONE
flashultra Mar 4, 2023
f1f1e11
New implementation for BigIntException class
flashultra Mar 4, 2023
e4c22e6
Remove memory limit for PHP test
flashultra Mar 22, 2023
ec9646c
Fix for php test
flashultra Mar 23, 2023
5177449
Add from/to different base
flashultra Apr 6, 2023
0a7500c
Remove trace()
flashultra Apr 6, 2023
b664dcc
Fix for toString()
flashultra Apr 6, 2023
611d36f
Merge branch 'development' of https://github.com/HaxeFoundation/haxe …
flashultra Dec 26, 2023
fab6b83
Merge branch 'development' of https://github.com/HaxeFoundation/haxe …
flashultra Jan 6, 2024
5da8f75
Add Montgomery and Barrett reduction for modPow
flashultra Jan 6, 2024
0d6f584
Add bitlen()
flashultra Jan 6, 2024
4cb131d
Fix typo
flashultra Jan 6, 2024
2173c8a
Add compareMonty() and subtractMonty()
flashultra Jan 7, 2024
9293500
Change millerRabin().Fix compareMonty()
flashultra Jan 7, 2024
0011ee5
Merge branch 'HaxeFoundation:development' into development
flashultra Jan 7, 2024
4a1b149
Prime check for small numbers
flashultra Jan 7, 2024
d8d1b3d
Merge branch 'development' of https://github.com/flashultra/haxe into…
flashultra Jan 7, 2024
bffa60e
Debug Lua
flashultra Jan 8, 2024
e4faadc
Always init m_data
flashultra Jan 8, 2024
79e5779
Merge branch 'HaxeFoundation:development' into development
flashultra Dec 10, 2024
7bc65dc
Trigger GitHub actions
flashultra Dec 13, 2024
502f950
Debug BigIntRandomPrime [php,python]
flashultra Dec 13, 2024
8849e8b
Fix syntax err
flashultra Dec 13, 2024
422ec2d
Lua test - modInverse
flashultra Dec 13, 2024
5051966
Is toString() the problem ?
flashultra Dec 13, 2024
7452b85
Debug Lua
flashultra Dec 13, 2024
4448668
Debug compare()
flashultra Dec 13, 2024
274a2fd
Is the unsigned shift the problem ?
flashultra Dec 13, 2024
bddad70
Test sign() Lua
flashultra Dec 14, 2024
7c59327
Lua clampInt32 for compareInt()
flashultra Dec 14, 2024
71a8da6
Check compare() - Lua
flashultra Dec 14, 2024
9b376fc
Clamp left shift - Lua
flashultra Dec 14, 2024
8dcf4e5
[lua] Shift left doesn't work correctly
flashultra Dec 14, 2024
f851be7
Test left shift for Lua
flashultra Dec 14, 2024
ffec547
Sign test - Lua
flashultra Dec 14, 2024
4bbf648
Clamp lshift too, because -1 << 1 is 4294967294, but should be -2
flashultra Dec 14, 2024
6b634a2
Check for nil
flashultra Dec 14, 2024
0589e3d
What is nil ?
flashultra Dec 14, 2024
ad29bc8
Check testPrimeNumber
flashultra Dec 14, 2024
dee19e9
Lua nil debug
flashultra Dec 14, 2024
d2bbbcd
Debug
flashultra Dec 14, 2024
1c418e5
Debug Lua
flashultra Dec 14, 2024
3c19c45
Dbg Lua
flashultra Dec 14, 2024
eb9bd4b
Debug
flashultra Dec 14, 2024
fd76eb9
Remove debug ( failed)
flashultra Dec 14, 2024
975ab17
Last chance Lua
flashultra Dec 14, 2024
e91d2d2
Init m_count
flashultra Dec 14, 2024
8fbfcdb
Set m_data to null
flashultra Dec 14, 2024
83a3ae9
Debug
flashultra Dec 14, 2024
4a785f3
Debug
flashultra Dec 14, 2024
965a274
Debug
flashultra Dec 14, 2024
380e066
How num is null?
flashultra Dec 15, 2024
27e52a9
Trigger GitHub actions
flashultra Dec 16, 2024
6596762
Spooky compare call
flashultra Dec 16, 2024
008f6b0
wheel of fortune
flashultra Dec 16, 2024
abf4385
Check if this it the init poblem for Lua
flashultra Dec 16, 2024
5ee77da
Remove trace() and workaround
flashultra Dec 16, 2024
194cd6f
Remove Lua fix
flashultra Dec 17, 2024
df9906f
Merge branch 'HaxeFoundation:development' into development
flashultra Dec 17, 2024
bdf1e32
Add test for Python
flashultra Dec 17, 2024
ebfc736
Check why Python failed
flashultra Dec 17, 2024
903db1e
Check Python
flashultra Dec 17, 2024
428232e
Fix Python target
flashultra Dec 18, 2024
7778f19
Fix for Neko
flashultra Dec 19, 2024
1fd473b
Fix Neko II
flashultra Dec 19, 2024
3696602
Remove prime test for Lua and Cppia
flashultra Dec 20, 2024
3ec3f61
Fix for Cppia (see issue #11897)
flashultra Dec 20, 2024
4bf7251
Reorder const
flashultra Dec 20, 2024
542d1bd
Fix typo
flashultra Dec 20, 2024
51eaff1
Reorder static var
flashultra Dec 20, 2024
65f0dd7
Workaround Cppia
flashultra Dec 22, 2024
ab17d83
Fix Cppia II
flashultra Dec 22, 2024
432a3d1
Give up
flashultra Dec 22, 2024
c188704
I won't never give up, no, never give up, no
flashultra Dec 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
450 changes: 450 additions & 0 deletions std/haxe/math/bigint/BigInt.hx

Large diffs are not rendered by default.

772 changes: 772 additions & 0 deletions std/haxe/math/bigint/BigIntArithmetic.hx

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions std/haxe/math/bigint/BigIntExceptions.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C)2005-2022 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package haxe.math.bigint;

/* Original code courtesy Chuck Batson (github.com/cbatson) */
enum abstract BigIntExceptions(String) to String {
Copy link
Contributor

@sebthom sebthom Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just looked at the failing test. I think it is actually the other way around. enum abstract BigIntExceptions(String) from String if you want to use it like

} catch (e:String) {
   eq(BigIntExceptions.INVALID_ARGUMENT, e);
}

Maybe even better you do a catch-all:

} catch (e) {
   eq(BigIntExceptions.INVALID_ARGUMENT, e);
}

Then I believe you should don't need the from/to declarations at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think adding from String there would be nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So there are at least three options here:

  1. Return the first draft ( using class and string)
  2. Using enum abstract ( with from String to String ) similiar to Tink's approach ( https://github.com/haxetink/tink_core/blob/master/src/tink/core/Error.hx#L23)
  3. Extend haxe.Exception

The question here is how does the end user want to proceed with the error ?
Does it want to match it with if/else/switch case or trace the stack or something else ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the exceptions are strings and some other code throws a string exception with exactly the same value e.g. Invalid argument then the end user is not be able to distinguish that properly. So maybe typed exceptions might be better. When you search through the haxe std library however, there is no consistency and no clear direction visible what is the preferred approach (strings vs exception objects). No one really seems to care.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the other solution that I think was to create a BigInteException class (extends haxe.Exception) and create а new BigIntError.hx class ( which will use the current enum abstract implementation)
Example:

  1. BigIntError.hx
    enum abstract BigIntError(String) to String{
     var INVALID_ARGUMENT = "Invalid argument";
      .....
    }
  1. BigIntException.hx
class BigIntException extends haxe.Exception {
	public function new(error:BigIntError, ?previous:haxe.Exception) {
		super( error, previous);
	}
}

and call it with throw new BigIntException(BigIntError.INVALID_ARGUMENT);
If this is a better solution, I could implement it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea. Exceptions even if thrown as strings anyway result in the instantiation of an exception object, in this case haxe.ValueException. So there is also no performance drawback if you use a dedicated exception class.

var INVALID_ARGUMENT = "Invalid argument";
var BUFFER_TOO_SMALL = "Buffer too small";
var DIVISION_BY_ZERO = "Division by zero";
var NEGATIVE_EXPONENT = "Negative exponent";
var INVALID_OPERATION = "Invalid operation";
var NEGATIVE_MODULUS = "Modulus should be positive";
var EVEN_VALUES = "Both values are even";
}
151 changes: 151 additions & 0 deletions std/haxe/math/bigint/BigIntHelper.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright (C)2005-2022 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package haxe.math.bigint;

/* Original code courtesy Chuck Batson (github.com/cbatson) */
class BigIntHelper {
/**
"Numbler of leading zeros" - return the number of leading
0-value bits in the binary representation of `x`.
**/
public static function nlz(x:Int):Int {
// From "Hacker's Delight", Second Edition; Henry S. Warren, Jr.; 2013. Figure 5-15, p. 102.
var y:Int, m:Int, n:Int;

y = -(x >>> 16);
m = (y >> 16) & 16;
n = 16 - m;
x = x >>> m;

y = x - 0x100;
m = (y >> 16) & 8;
n = n + m;
x = x << m;

y = x - 0x1000;
m = (y >> 16) & 4;
n = n + m;
x = x << m;

y = x - 0x4000;
m = (y >> 16) & 2;
n = n + m;
x = x << m;

y = x >> 14;
m = y & (~y >> 1);
return n + 2 - m;
}

/**
"Ceiling power of two" -- round up to the least power of two
greater than or equal to input `x`, which is interpreted as
unsigned.
**/
public static function clp2(x:Int32):Int {
// From "Hacker's Delight", Second Edition; Henry S. Warren, Jr.; 2013. Figure 3-3, p. 62.
x = x - 1;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
return x + 1;
}

/**
Unsigned greater than comparison.

Returns `true` if `a > b` when both `a` and `b` are
interpreted as unsigned integers; `false` otherwise.
**/
public static inline function u32gtu32(a:Int, b:Int):Bool {
return (a ^ -2147483648) > (b ^ -2147483648); // unsigned comparison, see "Hacker's Delight" p. 25.
}

/**
Integer division of unsigned 32-bit integer by unsigned 16-bit integer.

Result is undefined when `divisor` <= 0 or `divisor` >= 2^16.
**/
public static function u32divu16(dividend:Int32, divisor:Int32):Int {
/*
Complicated because Haxe's division is always performed as
floating-point. Here we rely on the ability to exactly represent
a 31-bit integer as a Float. In other words, 64-bit floating
point is required.

TODO: Implement a method without this restriction.
TODO: Consider C++-specific optimization here.
*/

// From "Hacker's Delight", Second Edition; Henry S. Warren, Jr.; 2013. Section 9-3, p. 192.
var t:Int = divisor >> 31;
var nprime:Int = dividend & ~t;
var q:Int32 = Std.int((nprime >>> 1) / divisor) << 1;
var r:Int = dividend - q * divisor;
var c:Int = u32geu32(r, divisor) ? 1 : 0;
return q + c;
}

/**
Unsigned greater than or equal comparison.
Returns `true` if `a >= b` when both `a` and `b` are
interpreted as unsigned integers; `false` otherwise.
**/
public static inline function u32geu32(a:Int, b:Int):Bool {
return (a ^ -2147483648) >= (b ^ -2147483648); // unsigned comparison, see "Hacker's Delight" p. 25.
}

/**
Number of trailing zeros - return the number of trailing
0-value bits
**/
public static function ntz(x:Int32):Int {
if (x == 0)
return 32;
var y:Int;
var n:Int = 31;
y = x << 16;
if (y != 0) {
n -= 16;
x = y;
}
y = x << 8;
if (y != 0) {
n -= 8;
x = y;
}
y = x << 4;
if (y != 0) {
n -= 4;
x = y;
}
y = x << 2;
if (y != 0) {
n -= 2;
x = y;
}
return (n - ((x << 1) >>> 31));
}
}
68 changes: 68 additions & 0 deletions std/haxe/math/bigint/BigIntTools.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (C)2005-2022 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package haxe.math.bigint;

import haxe.math.bigint.BigIntExceptions;

/* Original code courtesy Chuck Batson (github.com/cbatson) */
class BigIntTools {
public static inline function isNull(value:BigInt):Bool {
var a:BigInt_ = value;
return a == null;
}

public static inline function isBigInt(value:Dynamic):Bool {
return Std.isOfType(value, BigInt_);
}

public static inline function castFrom(value:Dynamic):BigInt {
return new BigInt(Std.downcast(value, BigInt_));
}

public static function parseValueUnsigned(value:Dynamic):BigInt {
var bi:BigInt;
if (Std.isOfType(value, String)) {
bi = parseStringUnsigned(cast(value, String));
} else if (isBigInt(value)) {
var t = new MutableBigInt_();
t.copyFrom(castFrom(value));
return new BigInt(t);
} else if (Std.isOfType(value, Int)) {
bi = BigInt.fromInt(cast(value, Int));
} else {
throw BigIntExceptions.INVALID_ARGUMENT;
}
return bi;
}

private static function parseStringUnsigned(value:String):BigInt {
var result = new MutableBigInt_();
if (StringTools.startsWith(value, "0x")) {
result.setFromHexUnsigned(value.substr(2));
} else {
result.setFromString(value);
}
var result2:MutableBigInt = result;
return result2;
}
}
Loading