News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Decimal Fractions <--> Byte (Microchip FP) converter

Started by trastikata, Jan 13, 2022, 07:06 PM

Previous topic - Next topic

trastikata

I found an useful tool capable of converting decimal fractions to bytes using different floating point representations, including the 32b Microchip format.

I'm not suing it so often but from time to time it comes handy.

PI.jpg

John Drew

An interesting tool.
I'll try it out of curiosity, doubt I'd ever need it.
I wonder if it documents the methods.
I'll have a look when I'm on the computer.
John

shantanu@india

Feeling nostalgic... I once wrote a similar program in VB6 and uploaded it to the old forum.
Good old days when Fanie used to crack 100 jokes a day😂
Regards
Shantanu

top204

Here's the compiler's function I created many year ago to convert an IEEE754 Floating Point value to the Microchip 32-bit Floating Point format's seperate bytes:

//-----------------------------------------------------------------------------------------------------------------------------------------
// Convert an IEEE754 format Floating Point value to the Microchip 32-bit Floating Point 4 seperate bytes
// Input    : pFloatValue holds the Floating Point value to convert
// Output   : Returns the truncated integer value
//          : The converted values are held in Global_FloatValue1, Global_FloatValue2, Global_FloatValue3, and Global_FloatValue4:
//            Global_FloatValue1 = Exponent
//            Global_FloatValue2 = Mantissa 0
//            Global_FloatValue3 = Mantissa 1
//            Global_FloatValue4 = Mantissa 2
//
unsigned long FloatToInt(char *pFloatValue)
{
    double z;
    double UserFloat; 
    signed long e, k;
    char *EndStr;
    bool tSign;
    BYTE Exponent;
    unsigned long Byte1, Byte2, Byte3, Byte4;
    unsigned long Mantissa;
    unsigned long Truncated_Value;

    EndStr = "\0";
    DecimalSeparator = '.';
    UserFloat = strtod(pFloatValue, &EndStr);
    Truncated_Value = UserFloat;

    if(UserFloat == 0.0)
        {
            Byte1 = 0;
            Byte2 = 0;
            Byte3 = 0;
            Byte4 = 0;
        }
    else
        {
            //
            // Remember the original sign and make a positive value
            //
            tSign = false;
            if(UserFloat < 0)
                {
                    tSign = true;
                    UserFloat = UserFloat * -1;
                }
            //
            // Find the Exponent
            //
            z = log(UserFloat) / log(2.0);
            e = (signed long)(z);
            if(e > z) e--;
            Exponent = e + 127;
            sscanf(pFloatValue, "%f", &Mantissa);
            //
            // Create the byte values
            //
            Byte1 = Exponent;
            if(tSign == true) Byte2 = 0x80; else Byte2 = 0x00;
            Byte2 = Byte2 + ((Mantissa & 0x7F0000) >> 16);
            Byte3 = ((Mantissa & 0xFF00) >> 8);
            Byte4 = (Mantissa & 0xFF);
        }
    Global_FloatValue1 = Byte1;
    Global_FloatValue2 = Byte2;
    Global_FloatValue3 = Byte3;
    Global_FloatValue4 = Byte4;
    return Truncated_Value;
}

Notice it uses the Double  variable, which is the 64-bit Floating Point format, for its internal workings in the function, instead of the 32-bit Float  type? Because not even PCs can get the 32-bit Floating Point accurate enough for some values, and it is important to get the seperate byte values as accurate as they can be for the compiler. :-)