145 lines
5.8 KiB
MQL5
145 lines
5.8 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Def.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_DEF_MQH
|
|
#define TSNSTD_SRC_STRING_CONVDEF_DEF_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
//--- 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
|
|
}
|
|
//---
|
|
#endif // TSNSTD_SRC_STRING_CONVDEF_DEF_MQH
|
|
//+------------------------------------------------------------------+
|