CE-Programming / toolchain

Toolchain and libraries for C/C++ programming on the TI-84+ CE calculator series
https://ce-programming.github.io/toolchain/index.html
GNU Lesser General Public License v3.0
528 stars 53 forks source link

Improved the precision (and probably speed) of cbrtf. #509

Closed ZERICO2005 closed 4 days ago

ZERICO2005 commented 1 month ago

Minimum precision: 21.415037 bits at both +4.251052856e+02 and +7.969426579e+17 for cbrtf.

Precision is calculated as log2(fabs( true_cbrt(x) - approx_cbrt(x) )) - ilogb(fabs( true_cbrt(x) ))

The previous method of powf(x, 1.0f / 3.0f) had a minimum precision of 21.0 bits at +4.037431946e+02, and a minimum precision 19.299560 bits at +1.187444200e+07, slowly losing precision at larger magnitudes.

Precision tested with 32bit floats on x86_64

calc84maniac commented 1 month ago

I confirmed using the ez80sf tester that this does increase the number of passed tests to about 42% compared to the old function's 11% (when given non-negative finite inputs, since that's all the old function supported). It's not perfect, but it only claims to be 21.0 bits minimum precision so that's to be expected. I did notice for some huge inputs it returns NaN, though.

mateoconlechuga commented 1 month ago

powf(x, 1/3.f); is smaller tho

calc84maniac commented 1 month ago

powf(x, 1/3.f); is smaller tho

It's also semantically different (especially for negative inputs), so if someone wants to save space (assuming they're already using powf elsewhere) they can call powf like you just specified.

ZERICO2005 commented 1 month ago

powf(x, 1/3.f); is smaller tho

True, although it should probably be changed to this

if ( x == 0.0f || !isfinite(x) ) {
    return x;
}
return copysignf(powf(fabsf(x), 1/3.f), x);
ZERICO2005 commented 4 days ago

I will close this pull request as calc84maniac has written an assembly version of this function.