//+------------------------------------------------------------------+ //| Dbl.mqh | //| Copyright 2026, Niquel Mendoza. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, Niquel Mendoza." #property link "https://www.mql5.com" #property strict #ifndef TSNSTD_SRC_STRING_CONVDEF_DBL_MQH #define TSNSTD_SRC_STRING_CONVDEF_DBL_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "Def.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ namespace TSN { //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //--- // 5^q #define STRCONV_DBL_LOG2(q) ((((152170 + 65536) * (q)) >> 16) + 63) //--- union __UDoubleToLong { double d; long l; ulong u; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CDoubleParser { public: CDoubleParser(void) {} ~CDoubleParser(void) {} //--- static void ComputeDbl(const int q, ulong w, ulong& mantissa, int& power2); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // la idea con esto es caualr la mejor aproximacion para w × 10^q // w = mantisa (numeros significativos) // q = exponente decimal //--- #define MQLARTICLES_DBLPARSE_DBL_PRESICION (56) // real: ((P)<64)?(ulong)0xFFFFFFFFFFFFFFFF>>(P):(ulong)0xFFFFFFFFFFFFFFFF #define MQLARTICLES_DBLPARSE_PMASK(P) ((ulong)0xFFFFFFFFFFFFFFFF>>(P)) #define MQLARTICLES_DBLPARSE_PMASK_DBL (MQLARTICLES_DBLPARSE_PMASK(MQLARTICLES_DBLPARSE_DBL_PRESICION)) //--- static void CDoubleParser::ComputeDbl(const int q, ulong w, ulong& mantissa, int& power2) {/* //--- if(w == 0 || q < TSN_SMALLEST_POWER_OF_FIVE) // muy pequeño (0) { power2 = 0; mantissa = 0; return; } if(q > TSN_LARGEST_POWER_OF_FIVE) // muy grande (inf) { power2 = TSN_INFINITE_POWER; mantissa = 0; return; } //--- const int lz = CBitTricks::CLZ(w); w <<= lz; //--- ulong phi, plo; //--- algortimo de estimacino en si // valor - minimo posible (-(.)) // valor - (-x) // valor + x // la idea es como aseguramnso que q el reusltado de esto no es nefativo // en teoria nucna lo sera pro que tenemos que q como minimo vale -342 + 342 = 0 // como valor minimo const int index = int(q + (-TSN_SMALLEST_POWER_OF_FIVE)) << 1; // primera multiplicacion CNumberUtils::Mul64to128(w, g_tsn_power_of_five_128[index], phi, plo); if((phi & MQLARTICLES_DBLPARSE_PMASK_DBL) == MQLARTICLES_DBLPARSE_PMASK_DBL) { // mas presicion ulong shi = 0, slo = 0; CNumberUtils::Mul64to128(w, g_tsn_power_of_five_128[index + 1], phi, slo); plo += shi; if(shi > plo) // carry phi++; } //--- const int upperbit = int(phi >> 63); // upperbit 1=0 por lo que shift >0 const int shift = upperbit + (64 - TSN_MANTISSA_EXPLICIT_BITS - 3); //--- mantissa = phi >> shift; power2 = STRCONV_DBL_LOG2(q) + upperbit - lz - TSN_MINIMUM_EXPONENT; //--- if(power2 <= 0) // subnormal { const int s = -power2 + 1; if(s >= 64) { power2 = 0; mantissa = 0; return; } //--- mantissa >>= s; mantissa += (mantissa & 1); // redondeo mantissa >>= 1; // si es true 1 si no 0 power2 = (mantissa >= (1ULL << TSN_MANTISSA_EXPLICIT_BITS)); return; } //--- // if(plo <= 1 && // q >= TSN_MIN_EXPONENT_ROUND_TO_EVEN && // q <= TSN_MAX_EXPONENT_ROUND_TO_EVEN && // (mantissa & 3) == 1 && // (mantissa << shift) == phi) // { // mantissa &= (~1ULL); // forzar redondeo hacia abajo // } //--- redondeo final mantissa += (mantissa & 1); mantissa >>= 1; //--- correcion por carry if(mantissa >= (2ULL << TSN_MANTISSA_EXPLICIT_BITS)) { mantissa = (1ULL << TSN_MANTISSA_EXPLICIT_BITS); power2++; } //--- limpieza de implicto mantissa &= (~(1ULL << TSN_MANTISSA_EXPLICIT_BITS)); //--- clamp if(power2 >= TSN_INFINITE_POWER) { power2 = TSN_INFINITE_POWER; mantissa = 0; }*/ } } //+------------------------------------------------------------------+ #endif // TSNSTD_SRC_STRING_CONVDEF_DBL_MQH