Initial rough addition of the float type. IO ops don't build, tests to be added.
This commit is contained in:
parent
20618e11ed
commit
f29fb594a5
@ -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>
|
||||
|
@ -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" />
|
||||
|
@ -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" />
|
||||
|
343
mpir.net/mpir.net/HugeFloat.cpp
Normal file
343
mpir.net/mpir.net/HugeFloat.cpp
Normal 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
|
||||
};
|
1228
mpir.net/mpir.net/HugeFloat.h
Normal file
1228
mpir.net/mpir.net/HugeFloat.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user