2026-09-09 20:01:29 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| Common.mqh |
|
| | | //| Copyright 2026, Niquel Mendoza. |
|
| | | //| https://www.mql5.com |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2026, Niquel Mendoza."
|
| | | #property link "https://www.mql5.com"
|
| | | #property strict
|
| | |
|
| | | #ifndef BIGNUMBERSBYLEO_SRC_BASE_COMMON_MQH
|
| | | #define BIGNUMBERSBYLEO_SRC_BASE_COMMON_MQH
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | #include "..\\Utils\\Main.mqh"
|
| | | #include "Def.mqh"
|
| | | #include "..\\Utils\\DER.mqh"
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | struct BigIBase
|
| | | {
|
| | | protected:
|
| | | //--- Swap version con e tambien actuliza el vs8 del v..
|
| | | BigIBase(ulong& v[], const int vs_8);
|
2026-09-10 07:16:18 -05:00 | | | BigIBase(const int vs_8, ulong& v[]);
|
| | |
|
| | | //-- Se inicia desde un numero en especiifco y con un tamaño (Que tambien es la reserva)
|
2026-09-09 20:01:29 -05:00 | | | BigIBase(const ulong number, const int vs);
|
| | |
|
| | | //-- Se inicia con un valor de 0 pero la idea es reservar limbs inciiales\nada (32 defualt)
|
2026-09-10 07:16:18 -05:00 | | | BigIBase(int initial_reserve);
|
2026-09-09 20:01:29 -05:00 | | | BigIBase();
|
| | |
|
2026-09-11 12:15:57 -05:00 | | | //--- Cmp
|
| | | template <typename TNormAbs>
|
| | | int CmpInt(const BigIBase &b) const;
|
| | |
|
2026-09-09 20:01:29 -05:00 | | | public:
|
| | | //--- raw
|
| | | ulong m_v[];
|
| | | int m_v_s;
|
| | |
|
2026-09-10 12:25:44 -05:00 | | | //--- Resta:
|
| | | // v = this - v
|
| | | // se asume que v es menor que this siempre
|
| | | // ahora v es menor que this siempre (o tiene que serlo ya se garantiza)
|
| | | void RestarConYResEn(ulong &v[], int& vs) const;
|
| | |
|
2026-09-09 20:01:29 -05:00 | | |
|
| | | //--- Es par
|
| | | __forceinline bool IsPar() const { return BIGNUMERBYLEO_UINTEGER_IZ_PAR; }
|
| | |
|
| | | //--- es Zero
|
| | | __forceinline bool IsZero() const { return BIGNUMERBYLEO_UINTEGER_IZ_ZERO; }
|
2026-09-10 09:23:17 -05:00 | | | __forceinline bool IsNotZero() const { return BIGNUMERBYLEO_UINTEGER_IZ_NZERO; }
|
2026-09-09 20:01:29 -05:00 | | |
|
| | | //--- acceso a limbs (sin chekeo raw maxima velociad)
|
| | | __forceinline ulong operator[](const int limb_idx) const { return m_v[limb_idx]; }
|
| | |
|
| | | //---
|
| | | void SetBit(const ulong bit_pos, bool v);
|
| | | __forceinline bool GetBit(const ulong bit_pos) const;
|
| | |
|
| | |
|
2026-09-11 12:15:57 -05:00 | | |
|
2026-09-09 20:01:29 -05:00 | | |
|
| | | //--- Swap
|
| | | void Swap(BigIBase& other);
|
| | |
|
| | | //--- Bits
|
| | | ulong Ctz() const;
|
| | |
|
| | | //---
|
| | | __forceinline void RobarDe(BigIBase &other);
|
| | |
|
| | | //---
|
| | | template <typename TRandom>
|
| | | __forceinline void FillRandom();
|
| | |
|
| | |
|
2026-09-11 14:45:51 -05:00 | | | //---
|
| | | void UShiftLeft(const ulong b);
|
| | |
|
2026-09-09 20:01:29 -05:00 | | | //---- Static utils
|
| | | // CTZ (maximo comun para ambos a y b)
|
| | | static ulong CTZ_Commons(const BigIBase& a, const BigIBase& b);
|
| | |
|
| | | //-- EMPTY bufffers
|
| | | // Dado que requiero sobrecargar el constructo hay un tema si hago (int) y (long) dara errores
|
| | | // y habra ambiguedad parte aevecs necsito el mismo tipo (initial reserve y number)
|
| | | // asi qeu para egerera sobrecargar el parmtor #1 aveces pedira un buffer (arrray)
|
| | | // vacio.... o cualquier cosa... entonces par eso esta esto..
|
| | | static const int EMPTY_INITIAL_RESERVE[1];
|
| | | static const double EMPTY_NUMBER_EXACT[1];
|
| | | static const ENUM_TIMEFRAMES EMPTY_SWAP[1];
|
2026-09-10 07:16:18 -05:00 | | | static const float EMPTY_ROBAR_CHECK[1];
|
2026-09-09 20:01:29 -05:00 | | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Variables estaticas |
|
| | | //+------------------------------------------------------------------+
|
| | | const int BigIBase::EMPTY_INITIAL_RESERVE[1] = {0};
|
| | | const double BigIBase::EMPTY_NUMBER_EXACT[1] = {0.0};
|
| | | const ENUM_TIMEFRAMES BigIBase::EMPTY_SWAP[1] = {0};
|
2026-09-10 07:16:18 -05:00 | | | const float BigIBase::EMPTY_ROBAR_CHECK[1] = {0};
|
2026-09-09 20:01:29 -05:00 | | |
|
| | | //+------------------------------------------------------------------+
|
2026-09-10 07:16:18 -05:00 | | | //| Swap |
|
2026-09-09 20:01:29 -05:00 | | | //+------------------------------------------------------------------+
|
| | | // Nota v ya muere ahi noramlte esto lo usarimos en operator
|
| | | // pro que ahora v tiene size=0 nada
|
| | | BigIBase::BigIBase(ulong &v[], const int vs_8)
|
| | | : m_v_s(vs_8)
|
| | | {
|
| | | // ahora m_v tiene el desipcrity de v y asi rotan
|
| | | ArraySwap(m_v, v);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
2026-09-10 07:16:18 -05:00 | | | BigIBase::BigIBase(const int vs_8, ulong& v[])
|
2026-09-09 20:01:29 -05:00 | | | : m_v_s(vs_8)
|
| | | {
|
| | | // ahora m_v tiene el desipcrity de v y asi rotan
|
2026-09-10 09:23:17 -05:00 | | | if(vs_8 == 0) // no hay tamaño
|
2026-09-10 07:16:18 -05:00 | | | {
|
| | | ArrayResize(m_v, 1);
|
| | | m_v[0] = 0ULL;
|
| | | }
|
| | | else
|
| | | {
|
| | | ArraySwap(m_v, v);
|
| | | }
|
2026-09-09 20:01:29 -05:00 | | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
2026-09-10 07:16:18 -05:00 | | | //| Valor |
|
2026-09-09 20:01:29 -05:00 | | | //+------------------------------------------------------------------+
|
| | | BigIBase::BigIBase(const ulong number, const int vs)
|
| | | : m_v_s(vs)
|
| | | {
|
2026-09-10 07:16:18 -05:00 | | | ArrayResize(m_v, vs);
|
2026-09-09 20:01:29 -05:00 | | | m_v[0] = (number);
|
| | | }
|
| | |
|
2026-09-10 07:16:18 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| Default\Reserva |
|
2026-09-09 20:01:29 -05:00 | | | //+------------------------------------------------------------------+
|
| | | BigIBase::BigIBase()
|
2026-09-10 09:23:17 -05:00 | | | : m_v_s(BIGNUMERBYLEO_INITIAL_SIZE_ZERO)
|
2026-09-09 20:01:29 -05:00 | | | {
|
2026-09-10 07:16:18 -05:00 | | | ArrayResize(m_v, BIGNUMERBYLEO_INITIAL_RESERVE, BIGNUMERBYLEO_INITIAL_RESERVE); // tamaño inicial de reserva
|
2026-09-09 20:01:29 -05:00 | | | m_v[0] = 0ULL;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
2026-09-10 07:16:18 -05:00 | | | BigIBase::BigIBase(int initial_reserve)
|
2026-09-10 09:23:17 -05:00 | | | : m_v_s(BIGNUMERBYLEO_INITIAL_SIZE_ZERO)
|
2026-09-09 20:01:29 -05:00 | | | {
|
| | | ArrayResize(m_v, initial_reserve); // sion extra
|
| | | m_v[0] = 0ULL;
|
| | | }
|
| | |
|
2026-09-10 12:25:44 -05:00 | | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2026-09-11 12:15:57 -05:00 | | | // resta:
|
| | | // v = this - v
|
| | | // se asume que:
|
| | | // vs = es positivo (magnitud)
|
2026-09-10 12:25:44 -05:00 | | | void BigIBase::RestarConYResEn(ulong &v[], int& vs) const
|
| | | {
|
| | | //----
|
2026-09-11 14:45:51 -05:00 | | | //BIGNUMERBYLEO_INT_NORMALIZE(vs)
|
2026-09-10 12:25:44 -05:00 | | | ulong borrow = 0;
|
| | | int i = 0;
|
| | |
|
| | | //---
|
| | | const int lkc = vs;
|
| | | vs = m_v_s;
|
| | | if(vs > ArraySize(v))
|
| | | ArrayResize(v, vs);
|
| | |
|
| | | //---
|
| | | // Chekea ambos daod qeu b en caso pueda tener mas bytes esos ya no se procesan
|
| | | for(; i < lkc; i++)
|
| | | {
|
| | | const ulong res_bor = m_v[i] - borrow; // paso 0 (a-resto)
|
| | | const ulong res_f = res_bor - v[i]; // paso 1 (r-b)
|
| | | borrow = (m_v[i] < borrow) | // en caso sea menor (tipo m_v es 0 y borro viene cno 1
|
| | | // en ese caso tendremismo qeu prestarmos 1..
|
| | | // Igual aqui si el left menor al right tendra uqe prestartse
|
| | | (res_bor < v[i]);
|
| | | //Print(res_f);
|
| | | v[i] = res_f;
|
| | | }
|
| | | // sobra
|
| | | for(; i < m_v_s; i++)
|
| | | {
|
| | | const ulong r = m_v[i] - borrow;
|
| | | borrow = (m_v[i] < borrow); // si es menor enonces hubo uover
|
| | | v[i] = r;
|
| | | }
|
| | |
|
| | | //---
|
| | | BIGNUMBERSBYLEO_CLEAN_HIGH_ZEROS(v, vs)
|
2026-09-11 14:45:51 -05:00 | | | //BIGNUMERBYLEO_INT_SNEG(vs)
|
2026-09-10 12:25:44 -05:00 | | | }
|
| | |
|
| | |
|
2026-09-09 20:01:29 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | static ulong BigIBase::CTZ_Commons(const BigIBase &a, const BigIBase &b)
|
| | | {
|
| | | //---
|
| | | int k = 0;
|
| | | ulong num = 0;
|
| | | const int s = a.m_v_s > b.m_v_s ? b.m_v_s : a.m_v_s; // min
|
| | |
|
| | | //--- saltamos los 0
|
| | | ulong v = a.m_v[k] | b.m_v[k];
|
| | | while(true)
|
| | | {
|
| | | if(v) // alguno de ambos no es 0
|
| | | break;
|
| | |
|
| | | //--- sigue 0
|
| | | num += 64;
|
| | |
|
| | | //---
|
| | | // Aun nada pero todo 0
|
| | | // pero por lo visto almenos uno de los dos numeros es es 0
|
| | | if(++k >= s)
|
| | | return ULONG_MAX; // maximo posible ()
|
| | |
|
| | | //--- segimos
|
| | | v = a.m_v[k] | b.m_v[k];
|
| | | }
|
| | |
|
| | | //--- limb con valor..
|
| | | const ulong flag = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(v);
|
| | | return num + TSNTABLES_CTZ_64_GET_BIT(flag);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Ctz |
|
| | | //+------------------------------------------------------------------+
|
| | | ulong BigIBase::Ctz() const
|
| | | {
|
| | | //---
|
| | | int k = 0;
|
| | | ulong num = 0;
|
| | |
|
| | | //--- saltamos los 0
|
| | | ulong v = m_v[k];
|
| | | while(true)
|
| | | {
|
| | | //---
|
| | | if(v)
|
| | | break;
|
| | |
|
| | | //--- sigue 0
|
| | | num += 64;
|
| | |
|
| | | //---
|
| | | // Aun nada pero todo 0
|
| | | if(++k >= m_v_s)
|
| | | return ULONG_MAX; // maximo posible
|
| | |
|
| | | //---
|
| | | v = m_v[k];
|
| | | }
|
| | |
|
| | | //--- limb con valor..
|
| | | const ulong flag = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(v);
|
| | | return num + TSNTABLES_CTZ_64_GET_BIT(flag);
|
| | | }
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TRandom>
|
| | | __forceinline void BigIBase::FillRandom()
|
| | | {
|
| | | TRandom::RandomUlongArr(m_v, m_v_s);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2026-09-11 12:15:57 -05:00 | | | template <typename TNormAbs>
|
| | | int BigIBase::CmpInt(const BigIBase &b) const
|
2026-09-09 20:01:29 -05:00 | | | {
|
| | | // iniciales
|
| | | if(m_v_s > b.m_v_s)
|
| | | return BIGINTEGER_CMP_MAYOR;
|
| | | if(m_v_s < b.m_v_s)
|
| | | return BIGINTEGER_CMP_MENOR;
|
| | | // equal en size
|
2026-09-11 12:15:57 -05:00 | | | int i = TNormAbs::AbsS(m_v_s) - 1;
|
| | | for(; i >= 0; i--)
|
2026-09-09 20:01:29 -05:00 | | | {
|
| | | if(m_v[i] != b.m_v[i]) // no coindice
|
| | | return m_v[i] > b.m_v[i] ? BIGINTEGER_CMP_MAYOR : BIGINTEGER_CMP_MENOR;
|
| | | }
|
| | | return BIGINTEGER_CMP_EQ; // iguales
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void BigIBase::Swap(BigIBase &other)
|
| | | {
|
2026-09-11 12:15:57 -05:00 | | | BIGNUMERBYLEO_SWAP(m_v_s, other.m_v_s, int)
|
2026-09-09 20:01:29 -05:00 | | | ArraySwap(m_v, other.m_v);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | __forceinline void BigIBase::RobarDe(BigIBase &other)
|
| | | {
|
| | | m_v_s = other.m_v_s;
|
| | | ArraySwap(m_v, other.m_v);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | __forceinline bool BigIBase::GetBit(const ulong bit_pos) const
|
| | | {
|
| | | return bool(m_v[bit_pos >> 6] & (1ULL << (bit_pos & 63)));
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void BigIBase::SetBit(const ulong bit_pos, bool v)
|
| | | {
|
| | | m_v[bit_pos >> 6] &= (ulong(v) << (bit_pos & 63));
|
| | | }
|
| | |
|
| | |
|
2026-09-11 14:45:51 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void BigIBase::UShiftLeft(const ulong b)
|
| | | {
|
| | | //--- chekeamos 0 dado que 0<<x con x grande peude hacer crecer el tamaño artificilaemtne de mvs
|
| | | if(BIGNUMERBYLEO_UINTEGER_IZ_ZERO)
|
| | | return;
|
| | |
|
| | | //---
|
| | | const int els = int(b >> 6); // b / 64
|
| | | const int els_sob = int(b & 63); // % 64
|
| | |
|
| | | //---
|
| | | if(els_sob == 0) // exacto
|
| | | {
|
| | | //---
|
| | | m_v_s += els;
|
| | | if(m_v_s < ArraySize(m_v))
|
| | | ArrayResize(m_v, m_v_s);
|
| | |
|
| | | //---
|
| | | int i = m_v_s - 1;
|
| | | for(; i >= els; i--)
|
| | | m_v[i] = m_v[i - els];
|
| | |
|
| | | //---
|
| | | for(; i >= 0; i--)
|
| | | m_v[i] = 0ULL;
|
| | |
|
| | | //---
|
| | | return;
|
| | | }
|
| | |
|
| | | //---
|
| | | int r = m_v_s - 1; // read pointer
|
| | | const int srh = (64 - els_sob); // shr
|
| | | ulong hi = m_v[r]; // valor de lectura actual hi
|
| | | const ulong overflow = hi >> srh; // si los altos habia valor randeo del dhift en adelante
|
| | |
|
| | | //---
|
| | | m_v_s += els;
|
| | | int w = m_v_s - 1; // escritura en els-1 (depende de que tantos salots elsb haya)
|
| | | if(overflow)
|
| | | {
|
| | | if(++m_v_s > ArraySize(m_v)) // si la reserva actual es menor al vactual
|
| | | ArrayResize(m_v, m_v_s);
|
| | | m_v[m_v_s - 1] = overflow;
|
| | | }
|
| | | else
|
| | | {
|
| | | // no hay ovw enotnces nada
|
| | | if(m_v_s > ArraySize(m_v)) // si la reserva actual es menor al vactual
|
| | | ArrayResize(m_v, m_v_s);
|
| | | }
|
| | |
|
| | | //--- iter
|
| | | while(r > 0)
|
| | | {
|
| | | const ulong prev = m_v[--r]; // valor previo
|
| | | m_v[w--] = (hi << els_sob) | (prev >> srh); // (valor alto dezplaado) | (valor bajo overflow siguiente)
|
| | | hi = prev; // ahora el alto es nuestro prev (Curr)
|
| | | }
|
| | | m_v[w] = hi << els_sob; // terminos con el valor 0 o ultimo
|
| | | }
|
| | |
|
2026-09-09 20:01:29 -05:00 | | | }
|
| | |
|
| | | #endif // BIGNUMBERSBYLEO_SRC_BASE_COMMON_MQH
|
| | | //+------------------------------------------------------------------+
|
2026-09-10 07:16:18 -05:00 | | | /* Notas
|
| | | - FromBytes: Si se pasa un buffer vacio o con tamaño de 1 y valor 0, se interpreta como 0
|
| | | - Se asume que:
|
| | | 1. El buffer siempre tendra al menos un elemento y con valor 0
|
| | |
|
| | | */
|
| | | //+------------------------------------------------------------------+
|