Float size checks and ToDouble(out exp). Apparently duplicate work, committing before merging from remote.
This commit is contained in:
parent
4770c42686
commit
5ef1d11323
@ -83,6 +83,22 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatToAndFromDouble2()
|
||||
{
|
||||
using (var a = new HugeFloat())
|
||||
{
|
||||
a.SetTo(-123.25);
|
||||
|
||||
long exp;
|
||||
double c = a.ToDouble(out exp);
|
||||
Assert.IsTrue(c.Equals(-0.962890625));
|
||||
Assert.AreEqual(7L, exp);
|
||||
Assert.IsTrue(a.Equals(-123.25));
|
||||
Assert.AreEqual("-0.12325@3", a.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatToAndFromFloat()
|
||||
{
|
||||
@ -97,6 +113,73 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatToAndFromUlong()
|
||||
{
|
||||
using (var a = new HugeFloat())
|
||||
{
|
||||
ulong b = 0xF84739ABCDEF4876;
|
||||
a.SetTo(b);
|
||||
|
||||
a.Value = -a;
|
||||
ulong c = a.ToUlong();
|
||||
Assert.AreEqual(b, c);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatToAndFromLong()
|
||||
{
|
||||
using (var a = new HugeFloat())
|
||||
{
|
||||
long b = -0x784739ABCDEF4876;
|
||||
a.SetTo(b);
|
||||
|
||||
long c = a.ToLong();
|
||||
Assert.AreEqual(b, c);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatToUlong2()
|
||||
{
|
||||
using (var a = new HugeFloat())
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
ulong b = ulong.MaxValue;
|
||||
a.SetTo(b);
|
||||
a.Value = a + 1 - small;
|
||||
var c = a.ToUlong();
|
||||
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
a.Value = -1 + small;
|
||||
c = a.ToUlong();
|
||||
Assert.AreEqual(0UL, c);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatToLong2()
|
||||
{
|
||||
using (var a = new HugeFloat())
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
long b = long.MaxValue;
|
||||
a.SetTo(b);
|
||||
a.Value = a + 1 - small;
|
||||
var c = a.ToLong();
|
||||
|
||||
Assert.AreEqual(b, c);
|
||||
|
||||
b = long.MinValue;
|
||||
a.SetTo(b);
|
||||
a.Value -= 1 - small;
|
||||
c = a.ToLong();
|
||||
Assert.AreEqual(b, c);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatFromString()
|
||||
{
|
||||
@ -136,6 +219,126 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatFitsUlong()
|
||||
{
|
||||
using (var a = new HugeFloat(ulong.MaxValue))
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
Assert.IsTrue(a.FitsUlong());
|
||||
a.Value = a + 1;
|
||||
Assert.IsFalse(a.FitsUlong());
|
||||
a.Value = a - small;
|
||||
Assert.IsTrue(a.FitsUlong());
|
||||
a.SetTo(0);
|
||||
Assert.IsTrue(a.FitsUlong());
|
||||
a.Value = a - 1;
|
||||
Assert.IsFalse(a.FitsUlong());
|
||||
a.Value = a + small;
|
||||
Assert.IsTrue(a.FitsUlong());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatFitsLong()
|
||||
{
|
||||
using (var a = new HugeFloat(long.MaxValue))
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
Assert.IsTrue(a.FitsLong());
|
||||
a.Value = a + 1;
|
||||
Assert.IsFalse(a.FitsLong());
|
||||
a.Value = a - small;
|
||||
Assert.IsTrue(a.FitsLong());
|
||||
a.SetTo(long.MinValue);
|
||||
Assert.IsTrue(a.FitsLong());
|
||||
a.Value = a - 1;
|
||||
Assert.IsFalse(a.FitsLong());
|
||||
a.Value = a + small;
|
||||
Assert.IsTrue(a.FitsLong());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatFitsUint()
|
||||
{
|
||||
using (var a = new HugeFloat(uint.MaxValue))
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
Assert.IsTrue(a.FitsUint());
|
||||
a.Value = a + 1;
|
||||
Assert.IsFalse(a.FitsUint());
|
||||
a.Value = a - small;
|
||||
Assert.IsTrue(a.FitsUint());
|
||||
a.SetTo(0);
|
||||
Assert.IsTrue(a.FitsUint());
|
||||
a.Value = a - 1;
|
||||
Assert.IsFalse(a.FitsUint());
|
||||
a.Value = a + small;
|
||||
Assert.IsTrue(a.FitsUint());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatFitsInt()
|
||||
{
|
||||
using (var a = new HugeFloat(int.MaxValue))
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
Assert.IsTrue(a.FitsInt());
|
||||
a.Value = a + 1;
|
||||
Assert.IsFalse(a.FitsInt());
|
||||
a.Value = a - small;
|
||||
Assert.IsTrue(a.FitsInt());
|
||||
a.SetTo(int.MinValue);
|
||||
Assert.IsTrue(a.FitsInt());
|
||||
a.Value = a - 1;
|
||||
Assert.IsFalse(a.FitsInt());
|
||||
a.Value = a + small;
|
||||
Assert.IsTrue(a.FitsInt());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatFitsUshort()
|
||||
{
|
||||
using (var a = new HugeFloat(ushort.MaxValue))
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
Assert.IsTrue(a.FitsUshort());
|
||||
a.Value = a + 1;
|
||||
Assert.IsFalse(a.FitsUshort());
|
||||
a.Value = a - small;
|
||||
Assert.IsTrue(a.FitsUshort());
|
||||
a.SetTo(0);
|
||||
Assert.IsTrue(a.FitsUshort());
|
||||
a.Value = a - 1;
|
||||
Assert.IsFalse(a.FitsUshort());
|
||||
a.Value = a + small;
|
||||
Assert.IsTrue(a.FitsUshort());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatFitsShort()
|
||||
{
|
||||
using (var a = new HugeFloat(short.MaxValue))
|
||||
using (var small = new HugeFloat(0.0001))
|
||||
{
|
||||
Assert.IsTrue(a.FitsShort());
|
||||
a.Value = a + 1;
|
||||
Assert.IsFalse(a.FitsShort());
|
||||
a.Value = a - small;
|
||||
Assert.IsTrue(a.FitsShort());
|
||||
a.SetTo(short.MinValue);
|
||||
Assert.IsTrue(a.FitsShort());
|
||||
a.Value = a - 1;
|
||||
Assert.IsFalse(a.FitsShort());
|
||||
a.Value = a + small;
|
||||
Assert.IsTrue(a.FitsShort());
|
||||
}
|
||||
}
|
||||
|
||||
//private void AssertBetween(int min, int max, long actual)
|
||||
//{
|
||||
// Assert.IsTrue(actual >= min && actual <= max, "Expected {0} to {1}, actual {2}", min, max, actual);
|
||||
|
@ -891,21 +891,21 @@ namespace MPIR
|
||||
/// <returns>A string representation of the number in the specified base.</returns>
|
||||
String^ ToString(int base, bool lowercase) { return ToString(base, lowercase, 0); }
|
||||
|
||||
///// <summary>
|
||||
///// Returns the absolute value of the number as a ulong.
|
||||
///// <para>If the number is too big, then just the least significant bits that do fit are returned.
|
||||
///// </para>The sign of the number is ignored, only the absolute value is used.
|
||||
///// </summary>
|
||||
///// <returns>The absolute value as a ulong, possibly truncated to the least significant bits only.</returns>
|
||||
//mpir_ui ToUlong() { return MP(get_ui)(_value); }
|
||||
/// <summary>
|
||||
/// Returns the absolute value of the number as a ulong, truncating any fractional part.
|
||||
/// <para>If the number is too big, the result is undefined. Call FitsUlong() to check if the number will fit.
|
||||
/// </para>The sign of the number is ignored, only the absolute value is used.
|
||||
/// </summary>
|
||||
/// <returns>The absolute value as a ulong, with any fractional part truncated.</returns>
|
||||
mpir_ui ToUlong() { return MP(get_ui)(_value); }
|
||||
|
||||
///// <summary>
|
||||
///// Returns the value of the number as a long.
|
||||
///// <para>If the number is too big, then just the least significant bits that do fit are returned, with the same sign as the number.
|
||||
///// </para>When truncation occurs, the result is propobly not very useful. Call FitsLong() to check if the number will fit.
|
||||
///// </summary>
|
||||
///// <returns>The value as a ulong, possibly truncated to the least significant bits only.</returns>
|
||||
//mpir_si ToLong() { return MP(get_si)(_value); }
|
||||
/// <summary>
|
||||
/// Returns the value of the number as a long.
|
||||
/// <para>If the number is too big, the result is undefined. Call FitsLong() to check if the number will fit.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <returns>The value as a long, possibly truncated to the least significant bits only.</returns>
|
||||
mpir_si ToLong() { return MP(get_si)(_value); }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of the number as a double, truncating if necessary (rounding towards zero).
|
||||
@ -914,19 +914,20 @@ namespace MPIR
|
||||
/// <returns>The value as a double, possibly truncated.</returns>
|
||||
double ToDouble() { return MP(get_d)(_value); }
|
||||
|
||||
///// <summary>
|
||||
///// Returns the value of the number as a double, truncating if necessary (rounding towards zero), and returning the exponent separately.
|
||||
///// <para>The return is the mantissa, its absolute value will be in the range [0.5 - 1).
///// </para>If the source value is zero, both mantissa and exponent are returned as 0.
|
||||
///// </summary>
|
||||
///// <param name="exp">variable to store the exponent in.</param>
|
||||
///// <returns>The mantissa of the value as a double, possibly truncated.</returns>
|
||||
//double ToDouble([Out] mpir_si% exp)
|
||||
//{
|
||||
// mpir_si x;
|
||||
// auto result = MP(get_d_2exp)(&x, _value);
|
||||
// exp = x;
|
||||
// return result;
|
||||
//}
|
||||
/// <summary>
|
||||
/// Returns the value of the number as a double, truncating if necessary (rounding towards zero), and returning the exponent separately.
|
||||
/// <para>The return is the mantissa, its absolute value will be in the range [0.5 - 1).
/// </para>The exponent is binary, i.e. mantissa * 2^exp is the value of the source number.
|
||||
/// <para>If the source value is zero, both mantissa and exponent are returned as 0.
|
||||
/// </para></summary>
|
||||
/// <param name="exp">variable to store the exponent in.</param>
|
||||
/// <returns>The mantissa of the value as a double, possibly truncated.</returns>
|
||||
double ToDouble([Out] mpir_si% exp)
|
||||
{
|
||||
mpir_si x;
|
||||
auto result = MP(get_d_2exp)(&x, _value);
|
||||
exp = x;
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
@ -1045,19 +1046,41 @@ namespace MPIR
|
||||
|
||||
#pragma region Size checks
|
||||
|
||||
///// <summary>
|
||||
///// Returns the number of digits the number would take if written in the specified base.
|
||||
///// <para>The sign of the number is ignored, just the absolute value is used.
|
||||
///// </para>The result will be either exact or at most 2 characters too big.
|
||||
///// If <paramref name="base"/> is a power of 2, the result will always be exact.
|
||||
///// <para>If the number is 0, the result is always 3.
|
||||
///// </para>This function can be used to estimate the space required when converting to a string.
|
||||
///// The right amount of allocation is normally two more than the value returned,
|
||||
///// one extra for a minus sign and one for the null-terminator.
|
||||
///// <para>A slash between numerator and denominator is accounted for.</para></summary>
|
||||
///// <param name="base">Numeric base for the would-be string conversion, in the range from 2 to 62.</param>
|
||||
///// <returns>The number of digits the number would take written in the specified base, possibly 1 or 2 too big, not counting a leading minus.</returns>
|
||||
//mp_size_t ApproximateSizeInBase(int base) { return mpz_sizeinbase(&_value->_mp_num, base) + mpz_sizeinbase(&_value->_mp_den, base) + 1; }
|
||||
/// <summary>
|
||||
/// Returns true if the value of the float, when truncated to an integer, is in the ulong range.
|
||||
/// </summary>
|
||||
/// <returns>true if the value will fit in a ulong</returns>
|
||||
bool FitsUlong() { return MP(fits_ui_p)(_value) != 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the value of the float, when truncated to an integer, is in the long range.
|
||||
/// </summary>
|
||||
/// <returns>true if the value will fit in a long</returns>
|
||||
bool FitsLong() { return MP(fits_si_p)(_value) != 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the value of the float, when truncated to an integer, is in the uint range.
|
||||
/// </summary>
|
||||
/// <returns>true if the value will fit in a uint</returns>
|
||||
bool FitsUint() { return MP(fits_uint_p)(_value) != 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the value of the float, when truncated to an integer, is in the int range.
|
||||
/// </summary>
|
||||
/// <returns>true if the value will fit in a int</returns>
|
||||
bool FitsInt() { return MP(fits_sint_p)(_value) != 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the value of the float, when truncated to an integer, is in the ushort range.
|
||||
/// </summary>
|
||||
/// <returns>true if the value will fit in a ushort</returns>
|
||||
bool FitsUshort() { return MP(fits_ushort_p)(_value) != 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the value of the float, when truncated to an integer, is in the short range.
|
||||
/// </summary>
|
||||
/// <returns>true if the value will fit in a short</returns>
|
||||
bool FitsShort() { return MP(fits_sshort_p)(_value) != 0; }
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
@ -1541,7 +1541,7 @@ namespace MPIR
|
||||
/// <para>If the number is too big, then just the least significant bits that do fit are returned, with the same sign as the number.
|
||||
/// </para>When truncation occurs, the result is propobly not very useful. Call FitsLong() to check if the number will fit.
|
||||
/// </summary>
|
||||
/// <returns>The value as a ulong, possibly truncated to the least significant bits only.</returns>
|
||||
/// <returns>The value as a long, possibly truncated to the least significant bits only.</returns>
|
||||
mpir_si ToLong() { return MP(get_si)(_value); }
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user