• 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);
    

    and then converted to JavaScript:

    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,

    • The (float-32) typecast converts a nine digit integer to it's mantissa and characteristic - 32
    • Multiplied by a decimal constant, whose absent visible trailing zeros affect its characteristic -32
    • Typecasting to a (double int-64) improves accuraccy with both more digits in the mantissa and characteristic -64
    • Using the Math library in Javascript is prone to the mis-matched floating point values -32

    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.'

    http://www.espruino.com/InlineC



    Fourth link below has a nice table for comparrison

    Table of bits

    https://en.wikipedia.org/wiki/Floating-point_arithmetic

    float - 32 bits

    https://en.wikipedia.org/wiki/C_data_types

    Nice visual

    http://fabiensanglard.net/floating_point_visually_explained/

    Sec 5 Nice pictorial Sec 6 Round off error in mantissa

    http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)FloatingPoint.html

    Type casting in C

    https://www.tutorialspoint.com/cprogramming/c_type_casting

About

Avatar for Robin @Robin started