TsnTables2/Src/Bits/CLZ/CLZ.mqh
2026-08-27 13:13:08 -05:00

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
//+------------------------------------------------------------------+