Merge math.mp.Integer changes from the crypto branch

This commit is contained in:
Eugen Wissner 2017-03-21 19:25:12 +01:00
parent 85380ac3fc
commit b90517580e
2 changed files with 1363 additions and 1155 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** /**
* Copyright: Eugene Wissner 2016. * Copyright: Eugene Wissner 2016-2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0). * Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:belka@caraus.de, Eugene Wissner) * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
*/ */
module tanya.math; module tanya.math;
@ -79,7 +79,7 @@ body
} }
/// Ditto. /// Ditto.
I pow(I)(in auto ref I x, in auto ref I y, in auto ref I z) I pow(I)(const auto ref I x, const auto ref I y, const auto ref I z)
if (is(I == Integer)) if (is(I == Integer))
in in
{ {
@ -88,8 +88,8 @@ in
body body
{ {
size_t i = y.length; size_t i = y.length;
auto tmp2 = Integer(x.allocator), tmp1 = Integer(x, x.allocator); auto tmp1 = Integer(x, x.allocator);
Integer result = Integer(x.allocator); auto result = Integer(x.allocator);
if (x.length == 0 && i != 0) if (x.length == 0 && i != 0)
{ {
@ -109,7 +109,7 @@ body
result *= tmp1; result *= tmp1;
result %= z; result %= z;
} }
tmp2 = tmp1; auto tmp2 = tmp1;
tmp1 *= tmp2; tmp1 *= tmp2;
tmp1 %= z; tmp1 %= z;
} }
@ -134,15 +134,15 @@ pure nothrow @safe @nogc unittest
/// ///
unittest unittest
{ {
assert(cast(long) pow(Integer(3), Integer(5), Integer(7)) == 5); assert(pow(Integer(3), Integer(5), Integer(7)) == 5);
assert(cast(long) pow(Integer(2), Integer(2), Integer(1)) == 0); assert(pow(Integer(2), Integer(2), Integer(1)) == 0);
assert(cast(long) pow(Integer(3), Integer(3), Integer(3)) == 0); assert(pow(Integer(3), Integer(3), Integer(3)) == 0);
assert(cast(long) pow(Integer(7), Integer(4), Integer(2)) == 1); assert(pow(Integer(7), Integer(4), Integer(2)) == 1);
assert(cast(long) pow(Integer(53), Integer(0), Integer(2)) == 1); assert(pow(Integer(53), Integer(0), Integer(2)) == 1);
assert(cast(long) pow(Integer(53), Integer(1), Integer(3)) == 2); assert(pow(Integer(53), Integer(1), Integer(3)) == 2);
assert(cast(long) pow(Integer(53), Integer(2), Integer(5)) == 4); assert(pow(Integer(53), Integer(2), Integer(5)) == 4);
assert(cast(long) pow(Integer(0), Integer(0), Integer(5)) == 1); assert(pow(Integer(0), Integer(0), Integer(5)) == 1);
assert(cast(long) pow(Integer(0), Integer(5), Integer(5)) == 0); assert(pow(Integer(0), Integer(5), Integer(5)) == 0);
} }
/** /**
@ -170,3 +170,31 @@ unittest
known.each!((ref x) => assert(isPseudoprime(x))); known.each!((ref x) => assert(isPseudoprime(x)));
} }
/**
* Params:
* I = Value type.
* x = Value.
*
* Returns: The absolute value of a number.
*/
I abs(I : Integer)(const auto ref I x)
{
auto result = Integer(x, x.allocator);
result.sign = Sign.positive;
return result;
}
/// Ditto.
I abs(I : Integer)(I x)
{
x.sign = Sign.positive;
return x;
}
/// Ditto.
I abs(I)(const I x)
if (isIntegral!I)
{
return x >= 0 ? x : -x;
}