forked from nique_372/TsnTables
192 lines
7.3 KiB
MQL4
192 lines
7.3 KiB
MQL4
//+------------------------------------------------------------------+
|
|
//| CLZ.mqh |
|
|
//| Copyright 2026, Niquel Mendoza |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2026, Niquel Mendoza"
|
|
#property link "https://www.mql5.com"
|
|
#property strict
|
|
|
|
#ifndef TSNTABES_SRC_BITS_CLZ_CLZ_MQH
|
|
#define TSNTABES_SRC_BITS_CLZ_CLZ_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#include "..\\H.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
namespace TSN
|
|
{
|
|
//+------------------------------------------------------------------+
|
|
//| Count Leading Zeros |
|
|
//+------------------------------------------------------------------+
|
|
/*
|
|
La idea es la misma que con SWAR solo que leading zeros cuenta cuantso ceros
|
|
hasta el primer 1 empzamendo desde el byte mas significativo...
|
|
*/
|
|
//---
|
|
#define TSN_TABLES_CLZ_CONSTANT_MAGIC64 (0x03F79D71B4CB0A89)
|
|
#define TSN_TABLES_CLZ_CONSTANT_MAGIC32 (0x07C4ACDD)
|
|
#define TSN_TABLES_CLZ_CONSTANT_MAGIC16 (0x0F65)
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Tablas |
|
|
//+------------------------------------------------------------------+
|
|
//--- tabla (en base a una seucnai de 6 bits nos da una posicion)
|
|
const int g_tsntables_clz[64] =
|
|
{
|
|
63, 16, 62, 7, 15, 36, 61, 3,
|
|
6, 14, 22, 26, 35, 47, 60, 2,
|
|
9, 5, 28, 11, 13, 21, 42, 19,
|
|
25, 31, 34, 40, 46, 52, 59, 1,
|
|
17, 8, 37, 4, 23, 27, 48, 10,
|
|
29, 12, 43, 20, 32, 41, 53, 18,
|
|
38, 24, 49, 30, 44, 33, 54, 39,
|
|
50, 45, 55, 51, 56, 57, 58, 0
|
|
};
|
|
//---
|
|
const int g_tsntables_clz32[32] =
|
|
{
|
|
31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
|
|
23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0
|
|
};
|
|
//---
|
|
const int g_tsntables_clz16[16] =
|
|
{
|
|
15, 5, 14, 2, 4, 8, 13, 1, 6, 3, 9, 7, 10, 11, 12, 0
|
|
};
|
|
//---
|
|
const int g_tsntables_clz8[256] =
|
|
{
|
|
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#define TSNTABLES_CLZ_64(x) \
|
|
if(x == 0) \
|
|
return 64; \
|
|
x |= x >> 1;\
|
|
x |= x >> 2;\
|
|
x |= x >> 4;\
|
|
x |= x >> 8;\
|
|
x |= x >> 16;\
|
|
x |= x >> 32;\
|
|
return g_tsntables_clz[((x * TSN_TABLES_CLZ_CONSTANT_MAGIC64) >> 58)];\
|
|
|
|
//+------------------------------------------------------------------+
|
|
#define TSNTABLES_CLZ_32(x) \
|
|
if(x == 0)\
|
|
return 32; \
|
|
x |= x >> 1;\
|
|
x |= x >> 2;\
|
|
x |= x >> 4;\
|
|
x |= x >> 8;\
|
|
x |= x >> 16;\
|
|
return g_tsntables_clz32[((x * TSN_TABLES_CLZ_CONSTANT_MAGIC32) >> 27)];\
|
|
|
|
//+------------------------------------------------------------------+
|
|
#define TSNTABLES_CLZ_16(x) \
|
|
if(x == 0)\
|
|
return 16;\
|
|
x |= x >> 1;\
|
|
x |= x >> 2;\
|
|
x |= x >> 4;\
|
|
x |= x >> 8;\
|
|
return g_tsntables_clz16[((x * TSN_TABLES_CLZ_CONSTANT_MAGIC16) >> 12)];
|
|
|
|
//+------------------------------------------------------------------+
|
|
#define TSNTABLES_CLZ_8(x) return g_tsntables_clz8[x];
|
|
|
|
//+------------------------------------------------------------------+
|
|
#define TSNTABLES_CLZ_FUNC(ALG, RET) \
|
|
static int CBitTricks::CLZ(RET x) \
|
|
{ \
|
|
ALG(x) \
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
// lo hice asi dado qeu en mis evbnchs la version con tempaltes
|
|
// espenraod a que el compialdr en maximo elimian dead code (sizeof() .. = ..) no lo hacia
|
|
// y habiad ifenia entre ese template y el coidgo CLZ normal... asi que pro eso hice esto..
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_64, ulong)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_64, long)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_64, datetime)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_32, color)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_32, int)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_32, uint)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_16, short)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_16, ushort)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_8, char)
|
|
TSNTABLES_CLZ_FUNC(TSNTABLES_CLZ_8, uchar)
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Alg |
|
|
//+------------------------------------------------------------------+
|
|
//---
|
|
/*
|
|
La idea con la tabla y todo esto es que lo que haremos sera:
|
|
1. tomamos un x de entrada e iremos dezplanzando y combinadndo con el mismo x
|
|
la idea es dezplazar el x y expnadir los bits mas significativos hascia la derecha
|
|
como formar un caminimo tipo si tenemos
|
|
0000 10000
|
|
la idea es temrinar con
|
|
0000 1111
|
|
Esto es imrpaote dado qeu luego al multiplicarle por la consante
|
|
se los altos se genera un poatron de 6 bits que luego traducimos con la tabla
|
|
este patron se genera como parte del numero al que se multiplica por eejemplo
|
|
|
|
|
|
0000000000000000000000000000000011111111111111111111111111111111
|
|
|
|
// justo los altos en 0 daod que el carry hara el trabajo final
|
|
0000001111110111100111010111000110110100110010110000101010001001 *
|
|
0000000000000000000000000000000011111111111111111111111111111111
|
|
|
|
0000001111110111100111010111000110110100110010110000101010001001
|
|
0000001111110111100111010111000110110100110010110000101010001001
|
|
0000001111110111100111010111000110110100110010110000101010001001
|
|
... se reite 32 veces
|
|
luego de sumar con carry etc da:
|
|
|
|
1011 0000 1101 0011 0110 1101 0001 0111 0100 1011 0011 0100 1111 0101 0111 0111
|
|
|
|
>> 58
|
|
|
|
0010 1100
|
|
este es el patron = 44
|
|
y si lo traducimos con la talga ese patron en espeico nos da 32
|
|
justo
|
|
esto funciona dado qeu esa consante si vamos cojiendo ventanas de 6 64 veces (y circularmente)
|
|
te daras cuenta uqe cada seuncia es unica entonces con esto podemos darle un patron unico a
|
|
cada bit y justo esto es lo que permite identificar a cada bit..
|
|
|
|
Esto mismo aplica con CTZ (que lo define en swar)
|
|
*/
|
|
|
|
//---
|
|
}
|
|
#endif // TSNTABES_SRC_BITS_CLZ_MAIN_MQH
|
|
//+------------------------------------------------------------------+
|