Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Single precision converter for floating point

I hope someone can help with this. I've not been able to google my way out of this problem. I want to convert floating point numbers to single precision in hex and storing it in some file for initializing memory and then inputting this data to floating point IPs for further processing. Could anyone suggest any tools available to do this?

Thanks.

20 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    if you write a C program to printf %x a floating point variable what happens?

    --- Quote End ---

    The compiler complains *and* you get the wrong answer. Other than that...

    You need to fool the compiler a little with the typecast and reference/de-reference...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    ah well i would have typecast after i got the complaining, then i would have stumbled upon your answer :)

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    @donq, How'd you get the clue though that this will work? This really is making a fool out of the compiler!

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The longer version (the one that got eaten by the 'internets') explained a little more.

    There might be an easier way but this way does it (step by step) by extracting a pointer to the 32-bit value (&value), typecasting that pointer into a pointer to a 32-bit int (unsigned int *), then taking the value pointed to by this pointer (*). That value is passed to printf to print it as a hex value ("%08X").

    The best part is that all the hard work is done by the pre-processor by just controlling the way that printf looks at the value. There is really no conversion done at all, it just prints it the way it sees it, only now it sees it as an int.

    All the 'easy' ways generally wind up with the value being actually converted to an int (e.g. 6.8 truncates into 6) then printing the value of the int. not what you want.

    This way winds up only being about 6 RISK machine instructions to load the value and format string into registers, then a call to '_printf'.

    I've always though the 'best' code is no code at all. Let the pre-processor do all the work!:)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    float value = 6.8;
    printf("%08X",*(unsigned int *)(&value)) ;
    There might be an easier way but this way does it (step by step) by extracting a pointer to the 32-bit value (&value), typecasting that pointer into a pointer to a 32-bit int (unsigned int *), then taking the value pointed to by this pointer (*). That value is passed to printf to print it as a hex value ("%08X").

    --- Quote End ---

    I have used this solution before. If you have a good understanding of how things work at a low level, it's actually pretty straight forward.

    An alternative approach for the curious:

    union
    {
        float f;
        unsigned int i;
    }
    value;
    value.f = 6.8;
    printf("%08X", value.i);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    When I first saw the code I thought that the (unsigned int *) part was a mistake and I changed it to (unsigned float *). Code worked with this modification as well.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    ... and I changed it to (unsigned float *). ...

    --- Quote End ---

    Not exactly sure what an unsigned float is (sort of like jumbo shrimp). What compiler are you using that didn't flag this as an error of some sort?

    I think the compiler must have used the unsigned as an unsigned int, ignored the float part, and then treated it the same as my original. I would hope that (float *) would not work because that would put you right back where you started.

    The 'union' way of doing it is semantically different, but an identical end-effect. Just looking at the same value in a different way.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Microsoft C Compiler, now that I see more carefully I do get this warning when compiling code:

    'unsigned' : can not be used with type 'float'