BigNumberByLeo/Src/Base/Main.mqh
Nique_372 4be5c61de5
2026-08-14 08:53:35 -05:00

219 lines
7.2 KiB
MQL5

//+------------------------------------------------------------------+
//| Main.mqh |
//| Copyright 2026, Niquel Mendoza |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza"
#property link "https://www.mql5.com"
#property strict
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define BIGUINTEGER_BY_LEO_OP_WBITS(OP) \
ulong v[];\
const int max = (m_v_s > b.m_v_s ? m_v_s : b.m_v_s);\
ArrayResize(v, max);\
if(max == m_v_s)\
{\
for(int i = 0; i < b.m_v_s; i++)\
v[i] = m_v[i] OP b.m_v[i];\
for(int i = b.m_v_s; i < max; i++)\
v[i] = m_v[i] OP 0;\
}\
else\
{\
for(int i = 0; i < m_v_s; i++)\
v[i] = m_v[i] OP b.m_v[i];\
for(int i = m_v_s; i < max; i++)\
v[i] = b.m_v[i] OP 0;\
}\
return BigUInteger(v, max);
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// maximo numero a represetar = 2^31-1 (INT MAX) elementos * 64bits = 137438953408 este es el maximo numero de bits
// que peude tener un numero dado que un array como maximo tamaño dtiene INT_MAX elementos no peude tener mas
// y como cada elemtnos es un uint64_t entonces se peude repenstart ese numero * 64 bits
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
struct BigUInteger
{
//---
ulong m_v[];
int m_v_s;
//---
BigUInteger(const int vs_8);
// raw se transfiere (swaping)
BigUInteger(ulong& v[], const int vs_8);
//----
BigUInteger operator+(const BigUInteger& b);
BigUInteger operator-(const BigUInteger& b);
BigUInteger operator*(const BigUInteger& b);
BigUInteger operator/(const BigUInteger& b);
BigUInteger operator%(const BigUInteger& b);
//---
BigUInteger operator&(const BigUInteger& b);
BigUInteger operator|(const BigUInteger& b);
BigUInteger operator^(const BigUInteger& b);
// left
BigUInteger operator<<(const uchar b);
BigUInteger operator<<(const ushort b);
BigUInteger operator<<(const uint b);
BigUInteger operator<<(const ulong b);
BigUInteger operator<<(const char b);
BigUInteger operator<<(const short b);
BigUInteger operator<<(const int b);
BigUInteger operator<<(const long b);
// right
BigUInteger operator>>(const uint b);
//---
BigUInteger operator~();
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
BigUInteger BigUInteger::operator&(const BigUInteger& b)
{
//---
ulong v[];
const int l = (m_v_s > b.m_v_s ? b.m_v_s : m_v_s);;
ArrayResize(v, l);
//--- op
for(int i = 0; i < l; i++)
v[i] = m_v[i] & b.m_v[i];
// los bits sobranods serian x & 0 = 0 (no cuentan)
//---
return BigUInteger(v, l);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
BigUInteger BigUInteger::operator|(const BigUInteger& b)
{
BIGUINTEGER_BY_LEO_OP_WBITS( |)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
BigUInteger BigUInteger::operator^(const BigUInteger& b)
{
BIGUINTEGER_BY_LEO_OP_WBITS(^)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// solo para uint bien rexplicamdo
BigUInteger BigUInteger::operator<<(uint b)
{
//---
// a / 64 = a / (8 * 8) = a / (2^3 * 2^3) = a / (2^6)
// cuantas palrbas habra qeu mover extra (osea uqe no caban en un multipll)
const int els = int(b >> 6); // b / 64
const int els_sob = int(b & 63); // % 64
//---
ulong v[];
// suma + 1 en caso haya sobrante (osea digmoas se mueve 12 % 8 = 4 mas 1 comp´leto)
// a esto le sumamos el numero de (EL) que tenemos ahora mismo pero cuidado
// tenemos difenreis uniddades
// popr ejemplo si tenemos 128 bits de numero y queremos demzplacar 64 bits
// el numero tamaño serta 128+64 bits pero entre 8 pero hay un tema si hay sobrate tenmos que aumentar
// Por ejemplo con esta formula si quermos mover 70 bits en ese 128 seri aasi
const int vs = els + (els_sob > 0) + m_v_s;
// s=SLOTS
// VS = 1 (64) + 1 (6 sobro 6 y como es mayo r a 0) + 2 (128)
ArrayResize(v, vs);
ArrayInitialize(v, 0);
//---
int w = els + 1; // siguiente lo demas 0
ulong overflow = 0;
//--- Todo loq eu qeuepe aqui
for(int l = 0; l < m_v_s; l++)
{
const ulong y = m_v[l++];
//
v[w++] = (y << els_sob) | overflow;
// el overflow lo (que sale) y ya no cabe aqui
// lo guasrdmos en un temporal
overflow = y >> (64 - els_sob);
}
//--- termionamos con el overflow
if(overflow)
{
// en caso haya overflow lo ponemos en la ultiam poscino de lectrau
v[w] = overflow;
}
//--- return
return BigUInteger(v, vs);
}
//----- macro general
#define BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(TYPE) \
BigUInteger BigUInteger::operator<<(TYPE b)\
{\
const int els = int(b >> 6); \
const int els_sob = int(b & 63); \
ulong v[];\
const int vs = els + (els_sob > 0) + m_v_s;\
ArrayResize(v, vs);\
ArrayInitialize(v, 0);\
int w = els + 1; \
ulong overflow = 0;\
for(int l = 0; l < m_v_s; l++)\
{\
const ulong y = m_v[l++];\
v[w++] = (y << els_sob) | overflow;\
overflow = y >> (64 - els_sob);\
}\
if(overflow)\
{\
v[w] = overflow;\
}\
return BigUInteger(v, vs);\
}
//----- especializados
BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(uchar)
BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(ushort)
BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(ulong)
BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(char)
BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(short)
BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(int)
BIGUINTEGER_BY_LEO_OP_LEFT_DEZ(long)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
BigUInteger BigUInteger::operator>>(uint b)
{
}
}
//+------------------------------------------------------------------+
//