Initial rough addition of the float type. IO ops don't build, tests to be added.

This commit is contained in:
Alex Dyachenko 2014-05-27 13:30:13 -04:00
parent 20618e11ed
commit f29fb594a5
6 changed files with 1590 additions and 1 deletions

View File

@ -164,7 +164,9 @@
<Name>mpir.net</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="HugeFloatTests\" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>

View File

@ -142,6 +142,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\mpir.net\mpir.net\Common.h" />
<ClInclude Include="..\..\..\mpir.net\mpir.net\HugeFloat.h" />
<ClInclude Include="..\..\..\mpir.net\mpir.net\HugeInt.h" />
<ClInclude Include="..\..\..\mpir.net\mpir.net\HugeRational.h" />
<ClInclude Include="..\..\..\mpir.net\mpir.net\Random.h" />
@ -150,6 +151,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\mpir.net\mpir.net\AssemblyInfo.cpp" />
<ClCompile Include="..\..\..\mpir.net\mpir.net\HugeFloat.cpp" />
<ClCompile Include="..\..\..\mpir.net\mpir.net\HugeInt.cpp" />
<ClCompile Include="..\..\..\mpir.net\mpir.net\HugeRational.cpp" />
<ClCompile Include="..\..\..\mpir.net\mpir.net\Random.cpp" />

View File

@ -33,6 +33,9 @@
<ClInclude Include="..\..\..\mpir.net\mpir.net\HugeRational.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\mpir.net\mpir.net\HugeFloat.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\mpir.net\mpir.net\AssemblyInfo.cpp">
@ -50,6 +53,9 @@
<ClCompile Include="..\..\..\mpir.net\mpir.net\HugeRational.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\mpir.net\mpir.net\HugeFloat.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\..\mpir.net\mpir.net\ReadMe.txt" />

View File

@ -0,0 +1,343 @@
/*
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 "HugeFloat.h"
//#include "Random.h"
using namespace System::Runtime::InteropServices;
using namespace System::Text;
namespace MPIR
{
#pragma region construction
MPTYPE::MPTYPE()
{
AllocateStruct();
MP(init)(_value);
}
MPTYPE::MPTYPE(bool initialize)
{
AllocateStruct();
if(initialize)
MP(init)(_value);
}
MPTYPE::MPTYPE(MPEXPR_NAME^ value)
{
AllocateStruct();
MP(init)(_value);
value->AssignTo(_value);
}
MPTYPE::MPTYPE(IntegerExpression^ value)
{
AllocateStruct();
MP(init)(_value);
SetTo(value);
}
MPTYPE^ MPTYPE::Allocate(mp_bitcnt_t precision)
{
auto result = gcnew MPTYPE(false);
MP(init2)(result->_value, precision);
return result;
}
void MPTYPE::FromString(String^ value, int base)
{
AllocateStruct();
MP(init)(_value);
IntPtr ptr = Marshal::StringToHGlobalAnsi(value);
bool success = 0 == MP(set_str)(_value, (char*)(void*)ptr, base);
Marshal::FreeHGlobal(ptr);
if(!success)
{
DeallocateStruct();
throw gcnew ArgumentException("Invalid number", "value");
}
}
void MPTYPE::SetTo(String^ value, int base)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(value);
bool success = 0 == MP(set_str)(_value, (char*)(void*)ptr, base);
Marshal::FreeHGlobal(ptr);
if(!success)
throw gcnew ArgumentException("Invalid number", "value");
}
MPTYPE::MPTYPE(mpir_si value)
{
AllocateStruct();
MP(init_set_si)(_value, value);
}
MPTYPE::MPTYPE(mpir_ui value)
{
AllocateStruct();
MP(init_set_ui)(_value, value);
}
MPTYPE::MPTYPE(double value)
{
AllocateStruct();
MP(init_set_d)(_value, value);
}
#pragma endregion
#pragma region object overrides
String^ MPTYPE::ToString(int base, bool lowercase, int maxDigits)
{
auto result = gcnew StringBuilder();
//result->Append(this->Numerator->ToString(base, lowercase, maxDigits));
//result->Append((wchar_t)'/');
//result->Append(this->Denominator->ToString(base, lowercase, maxDigits));
return result->ToString();
}
int MPEXPR_NAME::GetHashCode()
{
IN_CONTEXT(this);
mp_limb_t hash = CTXT(0)->_mp_exp;
mp_limb_t* ptr = CTXT(0)->_mp_d;
for(int i = abs(CTXT(0)->_mp_size); i > 0; i--)
hash ^= *ptr++;
if(CTXT(0)->_mp_size < 0)
hash = (mp_limb_t)-(mpir_si)hash;
return hash.GetHashCode();
}
#pragma endregion
#pragma region Interface implementations
int MPEXPR_NAME::CompareTo(Object^ a, bool& valid)
{
valid = true;
if (IS_NULL(a))
return 1;
MPEXPR_NAME^ expr = dynamic_cast<MPEXPR_NAME^>(a);
if(!IS_NULL(expr))
return CompareTo(expr);
EvaluationContext context;
if(a->GetType() == mpir_ui::typeid)
{
ASSIGN_TO(context);
return MP(cmp_ui)(CTXT(0), (mpir_ui)a);
}
if(a->GetType() == mpir_si::typeid)
{
ASSIGN_TO(context);
return MP(cmp_si)(CTXT(0), (mpir_si)a);
}
if(a->GetType() == double::typeid)
{
ASSIGN_TO(context);
return MP(cmp_d)(CTXT(0), (double)a);
}
valid = false;
return 0;
}
int MPEXPR_NAME::CompareTo(Object^ a)
{
bool valid;
auto result = CompareTo(a, valid);
if (valid)
return result;
throw gcnew ArgumentException("Invalid argument type", "a");
}
int MPEXPR_NAME::CompareTo(MPEXPR_NAME^ a)
{
if (IS_NULL(a))
return 1;
IN_CONTEXT(this, a);
return MP(cmp)(CTXT(0), CTXT(1));
}
bool MPEXPR_NAME::Equals(Object^ a)
{
bool valid;
auto result = CompareTo(a, valid);
return valid && result == 0;
}
bool MPEXPR_NAME::Equals(MPEXPR_NAME^ a)
{
return CompareTo(a) == 0;
}
#pragma endregion
#pragma region Arithmetic
MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, +, Add, Flt, Flt)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, +, Add, Flt, Ui)
MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, +, Add, Flt, Ui)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, +, Add, Flt, Si)
MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, +, Add, Flt, Si)
MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, -, Subtract, Flt, Flt)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Flt, Ui)
MAKE_BINARY_OPERATOR_LLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Flt, Ui)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Flt, Si)
MAKE_BINARY_OPERATOR_LLIMB (MPEXPR_NAME, DEFINE, -, Subtract, Flt, Si)
MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, *, Multiply, Flt, Flt)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, *, Multiply, Flt, Ui)
MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, *, Multiply, Flt, Ui)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, *, Multiply, Flt, Si)
MAKE_BINARY_OPERATOR_LLIMB_R (MPEXPR_NAME, DEFINE, *, Multiply, Flt, Si)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, <<, ShiftLeft, Flt, Bits)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, >>, ShiftRight, Flt, Bits)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, ^, Power, Flt, Ui)
MAKE_UNARY_OPERATOR (MPEXPR_NAME, DEFINE, -, Negate, Flt)
MAKE_VOID_FUNCTION (MPEXPR_NAME, DEFINE, Abs, Flt)
MAKE_BINARY_OPERATOR_STANDARD (MPEXPR_NAME, DEFINE, /, Divide, Flt, Flt)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, /, Divide, Flt, Ui)
MAKE_BINARY_OPERATOR_LLIMB (MPEXPR_NAME, DEFINE, /, Divide, Flt, Ui)
MAKE_BINARY_OPERATOR_RLIMB (MPEXPR_NAME, DEFINE, /, Divide, Flt, Si)
MAKE_BINARY_OPERATOR_LLIMB (MPEXPR_NAME, DEFINE, /, Divide, Flt, Si)
DEFINE_UNARY_ASSIGNMENT_REF(Negate, Flt, MP(neg))
DEFINE_UNARY_ASSIGNMENT_REF(Abs, Flt, MP(abs))
DEFINE_BINARY_ASSIGNMENT_REF_REF(Add, Flt, MP(add))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Add, Flt, Ui, MP(add))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Add, Flt, Si, MP(add))
DEFINE_BINARY_ASSIGNMENT_REF_REF(Subtract, Flt, MP(sub))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Subtract, Flt, Ui, MP(sub))
DEFINE_BINARY_ASSIGNMENT_RATVAL_REF(Subtract, Ui, Flt, MP(sub))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Subtract, Flt, Si, MP(sub))
DEFINE_BINARY_ASSIGNMENT_RATVAL_REF(Subtract, Si, Flt, MP(sub))
DEFINE_BINARY_ASSIGNMENT_REF_REF(Multiply, Flt, MP(mul))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Multiply, Flt, Ui, MP(mul))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Multiply, Flt, Si, MP(mul))
DEFINE_BINARY_ASSIGNMENT_REF_REF(Divide, Flt, MP(div))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Divide, Flt, Ui, MP(div))
DEFINE_BINARY_ASSIGNMENT_RATVAL_REF(Divide, Ui, Flt, MP(div))
DEFINE_BINARY_ASSIGNMENT_REF_RATVAL(Divide, Flt, Si, MP(div))
DEFINE_BINARY_ASSIGNMENT_RATVAL_REF(Divide, Si, Flt, MP(div))
DEFINE_BINARY_ASSIGNMENT_REF_VAL(ShiftLeft, Flt, Bits, MP(mul_2exp))
DEFINE_BINARY_ASSIGNMENT_REF_VAL(ShiftRight, Flt, Bits, MP(div_2exp))
DEFINE_BINARY_ASSIGNMENT_REF_VAL(Power, Flt, Ui, MP(pow_ui))
#pragma endregion
#pragma region IO
#define chunkSize 1024
size_t MPTYPE::Write(Stream^ stream)
{
auto writtenNumerator = Numerator->Write(stream);
if(writtenNumerator == 0)
return 0;
auto writtenDenominator = Denominator->Write(stream);
if(writtenDenominator == 0)
return 0;
return writtenNumerator + writtenDenominator;
}
size_t MPTYPE::Read(Stream^ stream)
{
auto readNumerator = Numerator->Read(stream);
if(readNumerator == 0)
return 0;
auto readDenominator = Denominator->Read(stream);
if(readDenominator == 0)
return 0;
return readNumerator + readDenominator;
}
size_t MPTYPE::Write(TextWriter^ writer, int base, bool lowercase)
{
auto str = ToString(base, lowercase);
writer->Write(str);
return str->Length;
}
size_t MPTYPE::Read(TextReader^ reader, int base)
{
auto readNumerator = Numerator->Read(reader, base);
if(readNumerator == 0)
return 0;
size_t readDenominator = 0;
char c = reader->Peek();
if (c == '/')
{
reader->Read();
readDenominator = 1 + Denominator->Read(reader, base);
if(readDenominator == 1)
return 0;
}
return readNumerator + readDenominator;
}
#pragma endregion
#pragma region methods in other classes with rational parameters
void HugeInt::SetTo(MPEXPR_NAME^ value)
{
IN_CONTEXT(value);
mpz_set_f(_value, CTXT(0));
}
#pragma endregion
};

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,7 @@ namespace MPIR
{
ref class MpirRandom;
ref class RationalExpression;
ref class FloatExpression;
ref class MPTYPE;
ref class MPEXPR(Divide);
ref class MPEXPR(DivideUi);
@ -1650,6 +1651,13 @@ namespace MPIR
/// <param name="value">new value for the object</param>
void SetTo(RationalExpression^ value);
/// <summary>
/// Sets the value of the integer object. Any fractional portion is truncated.
/// <para>Do not change the value of an object while it is contained in a hash table, because that changes its hash code.
/// </para></summary>
/// <param name="value">new value for the object</param>
void SetTo(FloatExpression^ value);
/// <summary>
/// Swaps the values of two integers.
/// <para>This operation is a pointer swap and doesn't affect allocated memory.