3.2 KiB
Algoritmo de parseo de numeros (double) - (fast)
Aqui detallo la implemtancino de un aglrotimo que he diseñado (codigo en si.. no maths) para el parseo de str a double tomando varias ideas de otros parsers..
1. Inicio de variables
Por parte del user se garantiza como minimo 1 char valido, ahora si continuemos, en esta parte la idea sera iniclizacion 5 variables que usaremos...
val = 0.0; // valor inicial a 0.0
ulong v = 0; // valor double
uchar ch = (uchar)str[pos] ^ '0'; // primer caracter
long mask = 0; // mascara para negacion branchlees
int lock = pos; // posicion de lockeo (esto para hacer un rollback usando stringtodobule luego) y contar digitos
2. Primer caracter
En esta parte en caso el ch incila sea mayor a 9 (no sea un numero), haremos lo siguiente.. en un swith evaluamos dicho caracter en 3 casos:
- ('+' ^ '0'): entonces aumentamos pos en 1 y lock en 1 luego volvemos a calucalr el siguinetre caracter "xoreado" con '0' y en caso no sea un digito solo peude ser . si no lo es salimos..
- ('-' ^ '0'): modicmoas el valor de la mascakra en -1 y amentos el pos en 1, luego obtener el siguiente caracter y le aplicos un xor con '0' si es mayor a 9 buscmos que sea . si no lo es salimos.
- ('.' ^ '0'): ponemos ch en 0 y pos en -1 (para uqe luego en el primer ++ del leading zeros apunte al . y salga limpio para dec)
3. Parseo de la parte entera
En un while(true) haremos 3 "fases" para ir quirurgicamente.. iniclamte se nos gartaniza que ch es un valor valido (numero).. como hemos hecho en las primeras fases.. ahora en total haremos unas 19 iteraciones.. cada iteracion consiste en:
- multiplicar "v" * 10 y luego sumarle "ch"
- Aumentar pos en 1 y luego comparar con len del string si es mayor o igual (sale)
- En caso el shortchut del 2. no funciono "xoreamos" con '0', si ch es mayor a 10 entonces ya no tenemos mas digitos (sale)
1 Fase (leading zeros)
Ejeuctaimso una iteracion del algoritmo... tal cual... luego de eso vericaremos que
- Si v es 0 (!v), osea el primer caracter es 0 pero aun hay digitos numericos entonces ejecutaremos lo siguiente en un bucle:
- aumentar pos en 1 y comprar con <= con len, si es false sale
- luego ch lo asignaas con = como str[pos], si no es igual al caracter '0' sale Esto lo repetis.. por ejemplo se veria algo asi
do
{
if(++pos >= s_len)
return;
}
while((ch = (uchar)str[pos]) == '0');
Lugeo de eso vericias si pos es mayor o igualk a len si es asi entonces todo era 00000 por lo que sales limpio con un return, Si pasa eso.. entonces "xorea" ch con 0.. si es mayor a 9 entonces el lock lo pones como pos-1 esto debido a que tnemeo xy donde ahora mismo estamos en y el caracter con el digito real.. la idea es incluir al "ultimo" 000xy... osea solo qudarse con xy... y lueso sales con un break del bucle o sale solo si es while() en caso si sea un numero entonces lock=pos y luego ejeuctas una iteracion ahi mismo..
2 Fase (u18)
En un macro o repitiendo codigo repites 18 veces la "iteracion"
3 Fase
En caso se llegue aqui ya han pasado mas de 19 iutaciones por lo que ya estamos en el rango inseguro de ov de valor asi que haremos dos cosas seguiremos acomulando v
(ya me canse de redactar otro dia cuando tenga tiempo xddxdxdxd)