Extraer parte fraccionaria de doble *eficientemente* en C

Extraer parte fraccionaria de doble *eficientemente* en C


Estoy buscando tomar un doble IEEE y eliminar cualquier parte entera de la manera más eficiente posible.


quiero


1035 ->0
1045.23->0.23
253e-23=253e-23

No me importa el manejo adecuado de denormales, infinitos o NaN. No me importa jugar un poco, ya que sé que estoy trabajando con dobles IEEE, por lo que debería funcionar en todas las máquinas.


El código sin sucursales sería mucho más preferible.


Mi primer pensamiento es (en pseudocódigo)


char exp=d.exponent;
(set the last bit of the exponent to 1)
d<<=exp*(exp>0);
(& mask the last 52 bits of d)
(shift d left until the last bit of the exponent is zero, decrementing exp each time)
d.exponent=exp;

Pero el problema es que no puedo pensar en una forma eficiente de desplazar d hacia la izquierda hasta que el último bit del exponente sea cero, además parece que tendría que generar cero si no se configuraron todos los últimos bits. Esto parece estar relacionado con el problema del logaritmo en base 2.


Se agradecería mucho la ayuda con este algoritmo o con otros mejores.


Probablemente debería tener en cuenta que la razón por la que quiero un código sin ramas es porque quiero que se vectorice de manera eficiente.


Respuestas:


¿Qué tal algo simple?


double fraction = whole - ((long)whole);

Esto simplemente resta la parte entera del doble del valor en sí, el resto debe ser el componente fraccionario. Por supuesto, es posible que esto tenga algunos problemas de representación.