A re-implementation from the original C line
uint64_t frf = ((uint64_t)val << 19) / 32000000;
can be re-written to C code using floating point numbers
uint64_t frf = (uint64_t)((float)val * 0.016384);
var frf = Math.round(val * 0.016384);
(0.016384 is equal to Math.pow(2, 19) / 32000000)
Sat 2019.07.27 midnight
Two topics to follow, Topic 1
Burning the midnight oil here it's 3am, but learned a ton!
Thank you @maze1980 for yet another angle to approach. But thought about the solution on a rather long walk-about.
There are four areas to observe in that process.
See #10 2's compliment is used in original equation for bit shifting - just ones and zeros.
Floating point numbers are made up of a mantissa and characteristic, both with round off error suspectability.
Typecasting introduces yet another form of rounding.
@AkosLukacs pointed out in his worked examples the rounding error after six digits (base 10) of accuracy. #3 and #4
This reveals the limitation of the floating point engine Espruino uses, after around 5-6 digits.
The original equation required pow(2,19) - ~pow(2,~7.?) is approx ~pow(2,~11.?) is approx 0xFFx??? where the error creeps in.
This means we need accuracy better than 0x1xxx or 4096 which requires more accuracy within those 6 digits.
So, although the maths actually do work in that example,
it's the combination of rounding error that allows it to happen.
It appears that attempting to use floating point to solve a 2's compliment equation is not the way to go as the need is, to shift ones and zeros and not a representation of a number using a mantissa and characteristic. The accuracy is just not there.
And, sadly the kicker: E.compiledC
'Arithmetic with floats, doubles and uint64 may not work since it requires functions that won't be compiled in.'
Fourth link below has a nice table for comparrison
Table of bits
float - 32 bits
Sec 5 Nice pictorial Sec 6 Round off error in mantissa
Type casting in C
© Espruino, powered by microcosm.
Report a problem