diff --git a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj
index 4fb6a606..0599225f 100644
--- a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj
+++ b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj
@@ -155,6 +155,7 @@
+
Create
Create
diff --git a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters
index a423f954..5d6a08a6 100644
--- a/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters
+++ b/build.vc11/mpir.net/mpir.net/mpir.net.vcxproj.filters
@@ -56,6 +56,9 @@
Source Files
+
+ Source Files
+
diff --git a/mpir.net/mpir.net-tests/HugeFloatTests/ExpressionTests.cs b/mpir.net/mpir.net-tests/HugeFloatTests/ExpressionTests.cs
index d1c9d3f5..157674a2 100644
--- a/mpir.net/mpir.net-tests/HugeFloatTests/ExpressionTests.cs
+++ b/mpir.net/mpir.net-tests/HugeFloatTests/ExpressionTests.cs
@@ -62,6 +62,14 @@ namespace MPIR.Tests.HugeFloatTests
VerifyPartialResult(r, expr, -19);
expr = expr - (a / 4).Floor() + (b / 3).Ceiling() - (a / b).Truncate();
VerifyPartialResult(r, expr, -12);
+ expr = expr + (r.GetFloatBits(64) * 10).Ceiling();
+ VerifyPartialResult(r, expr, -10);
+ expr = expr + (r.GetFloatLimbsChunky(2, 4) << 233).Ceiling();
+ VerifyPartialResult(r, expr, -6);
+ expr = expr + (r.GetFloat() * 10).Floor();
+ VerifyPartialResult(r, expr, -2);
+ expr = expr + (r.GetFloatChunky(3) << 101).Truncate();
+ VerifyPartialResult(r, expr, 13);
MarkExpressionsUsed(allExpressions, expr);
}
diff --git a/mpir.net/mpir.net-tests/IntegrationTests/XmlCommentsTests.cs b/mpir.net/mpir.net-tests/IntegrationTests/XmlCommentsTests.cs
index e170da5b..c34d7e8c 100644
--- a/mpir.net/mpir.net-tests/IntegrationTests/XmlCommentsTests.cs
+++ b/mpir.net/mpir.net-tests/IntegrationTests/XmlCommentsTests.cs
@@ -75,6 +75,7 @@ namespace MPIR.Tests.HugeIntTests
var contents = File.ReadAllText(path);
contents = Regex.Replace(contents, "]*>", "paramref");
contents = Regex.Replace(contents, "?para>", "");
+ contents = contents.Replace("!System.Runtime.CompilerServices.IsLong", "");
var serializer = new XmlSerializer(typeof(XmlCommentsDoc));
using (var reader = new StringReader(contents))
diff --git a/mpir.net/mpir.net-tests/RandomTests/Random.cs b/mpir.net/mpir.net-tests/RandomTests/Random.cs
index 8e1d3d8e..8661d37b 100644
--- a/mpir.net/mpir.net-tests/RandomTests/Random.cs
+++ b/mpir.net/mpir.net-tests/RandomTests/Random.cs
@@ -184,5 +184,53 @@ namespace MPIR.Tests.RandomTests
Assert.AreEqual("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0000000000000000000000000000007F", a.ToString(16));
}
}
+
+ [TestMethod]
+ public void RandomHugeFloat()
+ {
+ using(var r = MpirRandom.Default())
+ using(var a = HugeFloat.Allocate(256))
+ {
+ r.Seed(12345789);
+ a.Value = r.GetFloat();
+ Assert.AreEqual("0.9E056474F27BEDF9AE62FB31A30B68DFA0B96F29D0C8767A88F8937D6F3A00FD@0", a.ToString(16));
+ }
+ }
+
+ [TestMethod]
+ public void RandomHugeFloatBits()
+ {
+ using(var r = MpirRandom.Default())
+ using(var a = HugeFloat.Allocate(256))
+ {
+ r.Seed(12345789);
+ a.Value = r.GetFloatBits(128);
+ Assert.AreEqual("0.A0B96F29D0C8767A88F8937D6F3A00FD@0", a.ToString(16));
+ }
+ }
+
+ [TestMethod]
+ public void RandomHugeFloatChunky()
+ {
+ using(var r = MpirRandom.Default())
+ using(var a = HugeFloat.Allocate(256))
+ {
+ r.Seed(12345789);
+ a.Value = r.GetFloatChunky(100);
+ Assert.AreEqual("0.7FFFFFFF0180000000000000000007FFFFFFFFFFFFFFFFFFF@-2EF", a.ToString(16));
+ }
+ }
+
+ [TestMethod]
+ public void RandomHugeFloatLimbsChunky()
+ {
+ using(var r = MpirRandom.Default())
+ using(var a = HugeFloat.Allocate(256))
+ {
+ r.Seed(12345789);
+ a.Value = r.GetFloatLimbsChunky(2, 100);
+ Assert.AreEqual("0.7FFFFFF8000007FFF@2C1", a.ToString(16));
+ }
+ }
}
}
diff --git a/mpir.net/mpir.net/HugeFloat.cpp b/mpir.net/mpir.net/HugeFloat.cpp
index 514d2b9d..5d861aa9 100644
--- a/mpir.net/mpir.net/HugeFloat.cpp
+++ b/mpir.net/mpir.net/HugeFloat.cpp
@@ -21,7 +21,6 @@ along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
#include "HugeInt.h"
#include "HugeRational.h"
#include "HugeFloat.h"
-//#include "Random.h"
using namespace System::Runtime::InteropServices;
using namespace System::Text;
diff --git a/mpir.net/mpir.net/HugeFloat.h b/mpir.net/mpir.net/HugeFloat.h
index 994cab1d..3dcfb406 100644
--- a/mpir.net/mpir.net/HugeFloat.h
+++ b/mpir.net/mpir.net/HugeFloat.h
@@ -87,7 +87,7 @@ namespace MPIR
auto ptr = &context.Temp[context.Index].MPTYPE_NAME;
CTXT(context.Index++) = ptr;
MP(init)(ptr);
- AssignTo(ptr);
+ AssignTo(ptr);
}
private:
@@ -767,6 +767,11 @@ namespace MPIR
DEFINE_UNARY_EXPRESSION_WITH_ONE (MPEXPR_NAME, Ceiling, Flt)
DEFINE_UNARY_EXPRESSION_WITH_ONE (MPEXPR_NAME, Truncate, Flt)
+ DEFINE_UNARY_EXPRESSION (MPEXPR_NAME, Random, MpirRandom^)
+ DEFINE_BINARY_EXPRESSION (MPEXPR_NAME, RandomBits, MpirRandom^, mp_bitcnt_t)
+ DEFINE_BINARY_EXPRESSION (MPEXPR_NAME, RandomChunky, MpirRandom^, mp_exp_t)
+ DEFINE_TERNARY_EXPRESSION (MPEXPR_NAME, RandomLimbsChunky, MpirRandom^, mp_size_t, mp_exp_t)
+
#pragma endregion
#pragma region HugeFloat class
diff --git a/mpir.net/mpir.net/Random.cpp b/mpir.net/mpir.net/Random.cpp
index ea406abc..f1862e58 100644
--- a/mpir.net/mpir.net/Random.cpp
+++ b/mpir.net/mpir.net/Random.cpp
@@ -26,16 +26,16 @@ namespace MPIR
DEFINE_ASSIGNMENT_PROLOG(Random)
{
IN_CONTEXT(Right);
- mpz_urandomm(destination, Left->_value, context.IntArgs[0]);
+ MP(urandomm)(destination, Left->_value, context.IntArgs[0]);
}
DEFINE_ASSIGNMENT_PROLOG(RandomBits)
{
- mpz_urandomb(destination, Left->_value, Right);
+ MP(urandomb)(destination, Left->_value, Right);
}
DEFINE_ASSIGNMENT_PROLOG(RandomBitsChunky)
{
- mpz_rrandomb(destination, Left->_value, Right);
+ MP(rrandomb)(destination, Left->_value, Right);
}
-};
\ No newline at end of file
+};
diff --git a/mpir.net/mpir.net/Random.h b/mpir.net/mpir.net/Random.h
index 08130792..4df7b518 100644
--- a/mpir.net/mpir.net/Random.h
+++ b/mpir.net/mpir.net/Random.h
@@ -23,8 +23,6 @@ using namespace System;
namespace MPIR
{
- ref class MpirRandom;
-
///
/// This class encapsulates a random number generator algorithm and state
///
@@ -234,5 +232,46 @@ namespace MPIR
IntegerExpression^ GetInt(IntegerExpression^ max) { return gcnew IntegerRandomExpression(this, max); }
#pragma endregion
+
+ #pragma region Random Float
+
+ ///
+ /// Generates a uniformly distributed random float in the range 0 <= n < 1, using the precision of the destination.
+ /// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
+ ///
+ /// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, generates the random number
+ FloatExpression^ GetFloat();
+
+ ///
+ /// Generates a uniformly distributed random float in the range 0 <= n < 1 with the specified number of significant bits in the mantissa.
+ /// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
+ ///
+ /// number of mantissa bits to generate
+ /// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, generates the random number
+ FloatExpression^ GetFloatBits(mp_bitcnt_t bitCount);
+
+ ///
+ /// Generates a random float with long strings of zeros and ones in the binary representation, using the precision of the destination.
+ /// Useful for testing functions and algorithms, since this kind of random numbers have proven
+ /// to be more likely to trigger corner-case bugs.
+ /// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
+ ///
+ /// The maximum absolute value for the exponent of the generated number. Generated exponent may be positive or negative.
+ /// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, generates the random number
+ FloatExpression^ GetFloatChunky(mp_exp_t maxExponent);
+
+ ///
+ /// Generates a random float with long strings of zeros and ones in the binary representation, and the specified number of significant limbs in the mantissa.
+ /// Useful for testing functions and algorithms, since this kind of random numbers have proven
+ /// to be more likely to trigger corner-case bugs.
+ /// As with all expressions, the result is not computed until the expression is assigned to the Value property or consumed by a method.
+ ///
+ /// number of mantissa limbs to generate.
+ /// The sign of this parameter determines the sign of the generated mantissa.
+ /// The maximum absolute value for the exponent of the generated number. Generated exponent may be positive or negative.
+ /// An expression object that, when assigned to the Value property or consumed by a primitive-returning method, generates the random number
+ FloatExpression^ GetFloatLimbsChunky(mp_size_t limbCount, mp_exp_t maxExponent);
+
+ #pragma endregion
};
};
diff --git a/mpir.net/mpir.net/RandomFloat.cpp b/mpir.net/mpir.net/RandomFloat.cpp
new file mode 100644
index 00000000..f19a46f0
--- /dev/null
+++ b/mpir.net/mpir.net/RandomFloat.cpp
@@ -0,0 +1,55 @@
+/*
+Copyright 2014 Alex Dyachenko
+
+This file is part of the MPIR Library.
+
+The MPIR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation; either version 3 of the License, or (at
+your option) any later version.
+
+The MPIR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the MPIR Library. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include "StdAfx.h"
+#include "HugeInt.h"
+#include "Random.h"
+#include "HugeRational.h"
+#include "HugeFloat.h"
+
+namespace MPIR
+{
+ MPEXPR_NAME^ MpirRandom::GetFloat() { return gcnew FloatRandomExpression(this); }
+ MPEXPR_NAME^ MpirRandom::GetFloatBits(mp_bitcnt_t bitCount) { return gcnew FloatRandomBitsExpression(this, bitCount); }
+ MPEXPR_NAME^ MpirRandom::GetFloatChunky(mp_exp_t maxExponent) { return gcnew FloatRandomChunkyExpression(this, maxExponent); }
+ MPEXPR_NAME^ MpirRandom::GetFloatLimbsChunky(mp_size_t limbCount, mp_exp_t maxExponent) { return gcnew FloatRandomLimbsChunkyExpression(this, limbCount, maxExponent); }
+
+ DEFINE_ASSIGNMENT_PROLOG(Random)
+ {
+ MP(urandomb)(destination, Operand->_value, MP(get_prec)(destination));
+ }
+
+ DEFINE_ASSIGNMENT_PROLOG(RandomBits)
+ {
+ MP(urandomb)(destination, Left->_value, Right);
+ }
+
+ DEFINE_ASSIGNMENT_PROLOG(RandomChunky)
+ {
+ MP(rrandomb)(destination, Left->_value, BITS_TO_LIMBS(MP(get_prec)(destination)), Right);
+ }
+
+ //TODO investigate why exponent does not seem to be in the promised range
+ //TODO implement "precision of destination" for context ops
+
+ DEFINE_ASSIGNMENT_PROLOG(RandomLimbsChunky)
+ {
+ MP(rrandomb)(destination, Left->_value, Middle, Right);
+ }
+};