Estoy buscando una manera de truncar un float
en un int
de una manera rápida y portátil (IEEE 754). La razón se debe a que en esta función el 50% del tiempo se gasta en el reparto:Conversión rápida de float a int (truncado)
float fm_sinf(float x) {
const float a = 0.00735246819687011731341356165096815f;
const float b = -0.16528911397014738207016302002888890f;
const float c = 0.99969198629596757779830113868360584f;
float r, x2;
int k;
/* bring x in range */
k = (int) (F_1_PI * x + copysignf(0.5f, x)); /* <-- 50% of time is spent in cast */
x -= k * F_PI;
/* if x is in an odd pi count we must flip */
r = 1 - 2 * (k & 1); /* trick for r = (k % 2) == 0 ? 1 : -1; */
x2 = x * x;
return r * x*(c + x2*(b + a*x2));
}
¿Has intentado compilar con '-ffast-math'? O omita la función copysign y use 'lrint()' en lugar de un (int) cast – hirschhornsalz
Sus consensos son innecesariamente (o demasiado optimistas) precisos. La precisión individual IEEE754 solo es válida para 6 cifras significativas, la precisión doble es válida para 15 dígitos y el doble largo varía entre compiladores y arquitecturas, pero incluso en las FPU x86, el formato nativo de 80 bits solo es válido para 20 dígitos. Si necesita ese nivel de precisión, el código no funcionará en ningún caso, y una biblioteca de precisión arbitraria sería * mucho * más lenta. – Clifford
@Clifford: Sé que son demasiado precisos, siempre me gusta calcular 35 dígitos para que pueda soportar cualquier cosa hasta 128 bits con solo copiar/pegar. – orlp