TSNStd/Src/String/ConvDef/Def.mqh

145 lines
5.8 KiB
MQL5

2026-10-09 12:34:15 -05:00
//+------------------------------------------------------------------+
//| Def.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com"
#property strict
2026-10-09 12:56:38 -05:00
#ifndef TSNSTD_SRC_STRING_CONVDEF_DEF_MQH
#define TSNSTD_SRC_STRING_CONVDEF_DEF_MQH
2026-10-09 12:34:15 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//--- utildiades para numeros (lemire) osea mul64 etc..
#include <TSN\\BInt\\NUtils.mqh>
//--- defines genricpoa para numeros
#include <TSN\\BInt\\Def.mqh>
//--- powexp table para srtconv
#include <TSN\\Tables\\PowExp.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| Numero de digitos |
//+------------------------------------------------------------------+
// digitos ≈ ceil(bytes * 8 * log10(2)) ≈ ceil(bytes * 2.408)
// log10(2) ≈ 0.30103
#define STRCONV_DIGITOS_UNSIGNED(T) (((sizeof(T) * 8 * 30103 + 99999) / 100000))
#define STRCONV_DIGITOS_SIGNED(T) (((sizeof(T) * 8 - 1) * 30103 + 99999) / 100000)
#define STRCONV_ZERO_XOR_MENOS ('0' ^ '-')
//---
#define STRCONV_U_FIRST_DIG(T) (sizeof(T)==1 ? 2 : sizeof(T)==2 ? 6 : sizeof(T)==4 ? 4 : 1)
// 1byte = 1 (128)
// 2byte = 3 (SHORT_MAX.. )
// 4byte = 2 (214.... INT_MAX)
// 8byte = 4 (9.... LONG_MAX)
#define STRCONV_I_FIRST_DIG(T) (sizeof(T)==1 ? 1 : sizeof(T)==2 ? 3 : sizeof(T)==4 ? 2 : 9)
//+------------------------------------------------------------------+
//| Defines generales para parseo de numeros\double |
//+------------------------------------------------------------------+
//--- Decimal
// X= implica "xor-eado" por '0'=48
// e xor '0' = 48 (dec) | 0x20 = 117
// E xor '0' = 117 | 0x20 = 117
// . xor '0' = 30
// - xor '0' = 29
#define STRCONV_DECX_CH_IS_MINUS(CH) (CH==29)
#define STRCONV_DECX_CH_IS_PDEC(CH) (CH==30)
#define STRCONV_DECX_CH_IS_E(CH) ((CH|0x20)==117)
#define STRCONV_DECX_CH_IS_DEC(CH) (STRCONV_DECX_CH_IS_PDEC(CH)||STRCONV_DECX_CH_IS_E(CH)) // es E\e o . decimal (inicio de double)
//--- algortimo principal
#define STRCONV_TOV_ALG(V, CH) V = (V << 3) + (V << 1) + CH;
//--- para double en especifico
#define STRCONV_TO_DOUBLE_ALG(EXPO, V) ((EXPO < 0) ? (V / g_potencias_de_10[-(EXPO)]) : (V * g_potencias_de_10[EXPO]))
//--- <16 un limite seguro dado que el maximo 1<<53-1 aun no lo alcanzamos con 15 digitos todos en 9...
#define STRCONV_MINSAFE_DOUBLE_DIG (16)
//--- para double por el momento... dado que ahora mismo la spec es
// no contar digitos signicativis entonces tenemos qeu ser conservidoares 15 digitos completos van con precision aqui
#define STRCONV_DOUBLE_SAFE_DBL(DIGTIS, EXPONENT) \
((DIGTIS) < STRCONV_MINSAFE_DOUBLE_DIG && EXPONENT>= -22 && EXPONENT <= 22)
// version con un plos (por ejemplo negativos o algo asi.)
#define STRCONV_DOUBLE_SAFE_DBL_P(DIGTIS, EXPONENT, V) \
((DIGTIS) < (STRCONV_MINSAFE_DOUBLE_DIG+(V)) && EXPONENT>= -22 && EXPONENT <= 22)
//--- parte final hacer el double con el exponenet + signo + mantissa
#define STRCONV_DOUBLE_MAKE_DBL_WMASK(EXPONENET, IV, MASK, VAL) \
IV |= ulong(EXPONENET) << TSN_MANTISSA_EXPLICIT_BITS; \
__UDoubleToLong u; \
u.u = IV | (MASK & (1LL << 63)); \
VAL = u.d;
//+------------------------------------------------------------------+
//| Mas generales para fucnioens especiivas de Conv |
//+------------------------------------------------------------------+
//--- Leading zeros check
#define STRCONV_LEADING_ZEROS_SKIP_STRICT(ACTION) \
while(++pos < s_len && (ch = (uchar)str[pos]) == '0') {} \
if((ch ^= '0') > 9) \
ACTION;
//--- it
#define STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_TOV_ALG(V, CH) \
if(++pos >= s_len || (CH = (uchar)str[pos] ^ '0') > 9) \
break;
//--- it has a bucle
#define STRCONV_TO_VALUE_BUCLE(V, CH) \
do { \
STRCONV_TOV_ALG(V, CH) \
} \
while(++pos >= s_len || (CH = (uchar)str[pos] ^ '0') > 9);
//--- unroolled 18
// 7 int
#define STRCONV_7_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH)
// 8 int
#define STRCONV_8_IT(V, CH) \
STRCONV_7_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH)
// 17 iteraciones
#define STRCONV_U17_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH) \
STRCONV_8_IT(V, CH) \
STRCONV_8_IT(V, CH)
// 18 iteraciones
#define STRCONV_U18_IT(V, CH) \
STRCONV_U17_IT(V, CH) \
STRCONV_TO_VALUE_IT(V, CH)
//---
#define STRCONV_SKIP_NUMBER while(++pos < s_len && ((uchar)str[pos] ^ '0') < 10) {}
// convertir el valor ya con todo y signo
}
//---
2026-10-09 12:56:38 -05:00
#endif // TSNSTD_SRC_STRING_CONVDEF_DEF_MQH
2026-10-09 12:34:15 -05:00
//+------------------------------------------------------------------+