Float Changing precision. MPIR 2.7.0 section 7.1 completed.
This commit is contained in:
parent
49775dbedb
commit
ef95a16dab
@ -31,7 +31,7 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
using (var a = new HugeFloat())
|
||||
{
|
||||
Assert.AreEqual(0, a.NumberOfLimbsUsed());
|
||||
Assert.AreEqual(3, a.Precision());
|
||||
Assert.AreEqual(128UL, a.Precision);
|
||||
Assert.AreEqual(128UL, a._allocatedPrecision);
|
||||
Assert.AreNotEqual(IntPtr.Zero, a.Limbs());
|
||||
Assert.AreEqual(0, a.Exponent());
|
||||
@ -46,7 +46,6 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
a.Dispose();
|
||||
|
||||
Assert.AreEqual(0, a.NumberOfLimbsUsed());
|
||||
Assert.AreEqual(0, a.Precision());
|
||||
Assert.AreEqual(IntPtr.Zero, a.Limbs());
|
||||
}
|
||||
|
||||
@ -57,7 +56,7 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
using (var a = new HugeFloat(n))
|
||||
{
|
||||
Assert.AreEqual(128UL, a._allocatedPrecision);
|
||||
Assert.AreEqual(3, a.Precision());
|
||||
Assert.AreEqual(128UL, a.Precision);
|
||||
Assert.AreEqual(1, a.Exponent());
|
||||
Assert.AreEqual("0." + n.ToString("X") + "@16", a.ToString(16));
|
||||
}
|
||||
@ -70,7 +69,7 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
using(var a = new HugeFloat(-n))
|
||||
{
|
||||
Assert.AreEqual(128UL, a._allocatedPrecision);
|
||||
Assert.AreEqual(3, a.Precision());
|
||||
Assert.AreEqual(128UL, a.Precision);
|
||||
Assert.AreEqual(1, a.Exponent());
|
||||
Assert.AreEqual("-0." + n.ToString("X") + "@16", a.ToString(16));
|
||||
}
|
||||
@ -83,7 +82,7 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
using(var a = new HugeFloat(n))
|
||||
{
|
||||
Assert.AreEqual(128UL, a._allocatedPrecision);
|
||||
Assert.AreEqual(3, a.Precision());
|
||||
Assert.AreEqual(128UL, a.Precision);
|
||||
Assert.AreEqual(1, a.Exponent());
|
||||
Assert.AreEqual("0." + n.ToString("X") + "@16", a.ToString(16));
|
||||
}
|
||||
@ -112,7 +111,7 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
{
|
||||
using (var a = HugeFloat.Allocate(193))
|
||||
{
|
||||
Assert.AreEqual(5, a.Precision());
|
||||
Assert.AreEqual(256UL, a.Precision);
|
||||
Assert.AreEqual(256UL, a._allocatedPrecision);
|
||||
Assert.AreEqual("0", a.ToString());
|
||||
}
|
||||
@ -164,5 +163,61 @@ namespace MPIR.Tests.HugeFloatTests
|
||||
FloatAssert.AreEqual("2340958273409578234095823045723490588.", b);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatSetPrecision()
|
||||
{
|
||||
using (var a = new HugeFloat(1))
|
||||
using (var b = new HugeFloat())
|
||||
{
|
||||
a.Value = a/3;
|
||||
b.Value = a;
|
||||
Assert.AreEqual(128UL, a._allocatedPrecision);
|
||||
Assert.AreEqual(128UL, a.Precision);
|
||||
Assert.AreEqual("0.3333333333333333333333333333333333333333@0", a.ToString());
|
||||
|
||||
a.Precision = 64;
|
||||
Assert.AreEqual(128UL, a._allocatedPrecision);
|
||||
Assert.AreEqual(64UL, a.Precision);
|
||||
Assert.AreEqual("0.333333333333333333333@0", a.ToString());
|
||||
Assert.AreEqual(a, b);
|
||||
|
||||
a.Precision = 128;
|
||||
Assert.AreEqual("0.3333333333333333333333333333333333333333@0", a.ToString());
|
||||
|
||||
a.Precision = 64;
|
||||
a.SetTo(1);
|
||||
a.Value = a / 3;
|
||||
Assert.AreNotEqual(a, b);
|
||||
Assert.AreEqual("0.333333333333333333333@0", a.ToString());
|
||||
|
||||
a.Precision = 128;
|
||||
Assert.AreNotEqual(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentException))]
|
||||
public void FloatSettingPrecisionOverAllocated()
|
||||
{
|
||||
using (var a = new HugeFloat())
|
||||
{
|
||||
a.Precision++;
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FloatReallocate()
|
||||
{
|
||||
using (var a = HugeFloat.Allocate(128))
|
||||
{
|
||||
Assert.AreEqual(128UL, a._allocatedPrecision);
|
||||
Assert.AreEqual(128UL, a.Precision);
|
||||
|
||||
a.Reallocate(256);
|
||||
Assert.AreEqual(256UL, a._allocatedPrecision);
|
||||
Assert.AreEqual(256UL, a.Precision);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,17 +171,6 @@ namespace MPIR.Tests
|
||||
return Accessors<HugeFloat>._value(x);
|
||||
}
|
||||
|
||||
internal static int Precision(this HugeFloat x)
|
||||
{
|
||||
if(_value(x) == IntPtr.Zero)
|
||||
return 0;
|
||||
|
||||
unsafe
|
||||
{
|
||||
return ((int*)_value(x).ToPointer())[0];
|
||||
}
|
||||
}
|
||||
|
||||
internal static int NumberOfLimbsUsed(this HugeFloat x)
|
||||
{
|
||||
if(_value(x) == IntPtr.Zero)
|
||||
|
@ -1070,6 +1070,41 @@ namespace MPIR
|
||||
|
||||
#pragma region Size checks
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the effective precision of the number without changing the memory allocated.
|
||||
/// <para>The number of bits cannot exceed the precision with which the variable was initialized or last reallocated.
|
||||
/// </para>The value of the number is unchanged, and in particular if it previously had a higher precision it will retain that higher precision.
|
||||
/// <para>New values assigned to the Value property will use the new precision.
|
||||
/// </para>This is an efficient way to use a float variable at different precisions during a calculation,
|
||||
/// perhaps to gradually increase precision in an iteration, or just to use various different
|
||||
/// precisions for different purposes during a calculation.
|
||||
/// <para>The number can be safely disposed after modifying its precision (this would not be the case in unmanaged MPIR).
|
||||
/// </para></summary>
|
||||
property mp_bitcnt_t Precision
|
||||
{
|
||||
mp_bitcnt_t get() { return MP(get_prec)(_value); }
|
||||
void set(mp_bitcnt_t value)
|
||||
{
|
||||
if(value > _allocatedPrecision)
|
||||
throw gcnew ArgumentException("Cannot set precision higher than allocated");
|
||||
|
||||
MP(set_prec_raw)(_value, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the precision of rop to be at least prec bits, reallocating its limbs data.
|
||||
/// <para>The value in rop will be truncated to the new precision.
|
||||
/// </para>This function requires a call to realloc, and so should not be used in a tight loop.
|
||||
/// </summary>
|
||||
/// <param name="precision">Minimum number of bits the allocated memory should hold for the mantissa.</param>
|
||||
void Reallocate(mp_bitcnt_t precision)
|
||||
{
|
||||
MP(set_prec_raw)(_value, _allocatedPrecision);
|
||||
MP(set_prec)(_value, precision);
|
||||
_allocatedPrecision = precision;
|
||||
}
|
||||
|
||||
///// <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.
|
||||
|
Loading…
Reference in New Issue
Block a user