Velocity Reviews > hexadecimal to float conversion

# hexadecimal to float conversion

pavithra.eswaran@gmail.com
Guest
Posts: n/a

 08-19-2005
Hi,
I would like to convert a single precision hexadecimal number to
floating point. The following program seems to work fine..
But I do not want to use scanf. I already have a 32 bit hexadecimal
number and would like to convert it into float. Can anyone tell me how
to do it?

int main()
{
float theFloat;
{
scanf("%f", &theFloat);
printf("0x%08X, %f\n", *(int *)&theFloat, theFloat);
}
return 0;
}

Jack Klein
Guest
Posts: n/a

 08-19-2005
On 18 Aug 2005 18:59:11 -0700, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote in
comp.lang.c:

> Hi,
> I would like to convert a single precision hexadecimal number to
> floating point. The following program seems to work fine..
> But I do not want to use scanf. I already have a 32 bit hexadecimal
> number and would like to convert it into float. Can anyone tell me how
> to do it?

Your post is extremely unclear, and your sample code does not seem to
match it. What is a "single precision hexadecimal number"? If you
are using scanf() you apparently have a text string. How was this
text string created?

#include <stdio.h> /* needed for prototype of scanf() */
#include <stdlib.h> /* needed for strto...() */

> int main()
> {
> float theFloat;
> {
> scanf("%f", &theFloat);

I don't understand, you seem to have a float right here already. It
appears that your implementation of scanf() understands and parses
floating point values in some hex format. Most unusual.

> printf("0x%08X, %f\n", *(int *)&theFloat, theFloat);
> }
> return 0;
> }

The truly safe alternative is to use fgets() to read the string into a
buffer and use strtod() to parse it into a double. If scanf() is
giving you the correct value, I guess strtod() will as well. But I
have a hard time believing that scanf() is turning a string of hex
into a float.

Perhaps the code you typed is not actually what your real code does?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html

Keith Thompson
Guest
Posts: n/a

 08-19-2005
(E-Mail Removed) writes:
> I would like to convert a single precision hexadecimal number to
> floating point. The following program seems to work fine..
> But I do not want to use scanf. I already have a 32 bit hexadecimal
> number and would like to convert it into float. Can anyone tell me how
> to do it?
>
> int main()
> {
> float theFloat;
> {
> scanf("%f", &theFloat);
> printf("0x%08X, %f\n", *(int *)&theFloat, theFloat);
> }
> return 0;
> }

That code (if you add the necessary #include directive) reads a
floating-point value from stdin and prints a hexadecimal string.
That's the opposite of what you're asking for, so saying it "seems to
work fine" is odd.

Your code assumes that int and float have the same size (and probably
the same alignment requirements). This is not a safe assumption.

You need to define exactly what you mean by "a single precision
hexadecimal number". I *think* you mean a hexadecimal string
corresponding to the representation of the floating-point value. If
so, this is also going to be non-portable.

For example, this program:

#include <stdio.h>

int main(void)
{
float f = 42.5;
unsigned int u = *(unsigned int*)&f;
printf("f = %g\n", f);
printf("u = 0x%X\n", u);
return 0;
}

happens to print

f = 42.5
u = 0x422A0000

on one implementation where I just tried it, but the hexadecimal
digits could be different on different systems. Most systems these
days use IEEE floating-point formats, but byte order can vary.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Eric Sosman
Guest
Posts: n/a

 08-19-2005
(E-Mail Removed) wrote:
> Hi,
> I would like to convert a single precision hexadecimal number to
> floating point. The following program seems to work fine..
> But I do not want to use scanf. I already have a 32 bit hexadecimal
> number and would like to convert it into float. Can anyone tell me how
> to do it?
>
> int main()
> {
> float theFloat;
> {
> scanf("%f", &theFloat);

This reads a group of characters in the usual form for
a floating-point constant, converts them to a `float' value,
and stores the result in `theFloat'. Or perhaps it fails
because there's no more input, or because the input stream
provided "blue Hawaii" instead of something that looks like
a number, or for some other reason. You should check the
value returned by the scanf() function to see whether it has
actually converted and stored a number.

> printf("0x%08X, %f\n", *(int *)&theFloat, theFloat);

The output may or may not be meaningful; on some machines
it might not work at all (for example, you might get SIGBUS
or some other kind of trap). You are trying to pretend that
the representation of the floating-point value `theFloat' can
also be understood as an `int', and this may or may not be so.
Many machines will give some kind of result, but different
machines are likely to give different results, and the C language
itself doesn't guarantee any result at all.

C does provide one special guarantee for a restricted form
of type-punning: it is permitted to access the individual bytes
of any object's representation through a pointer of the type
`unsigned char*'. For example, you could do

unsigned char *p = (unsigned char*)&theFloat;
printf ("0x");
while (p < (unsigned char*)(&theFloat + 1))
printf ("%02X", *p++);
printf (", %f\n", theFloat);

to print the individual bytes one at a time. (Even this isn't
perfect, by the way: a byte can have more than eight bits and
hence more than two hexadecimal digits. Machines where this is
the case are rare, but do exist.) This loop is guaranteed to
produce output and not to trap or anything like that, but the
output you get from machine A may not match that from machine B.

However, you actually asked about going the other way: from
a stream of hexadecimal digits to a floating-point value. You
could use a loop to convert the bytes one at a time (the inverse
of what's shown above), but the byte stream that produces 42.0
on machine A might produce -273.16 on machine B, or a NaN, or
even a signalling NaN that traps when you try to use it. There
is no One True Representation of a floating-point value as a
hexadecimal string -- so what, exactly, are you trying to do?

--
Eric Sosman
(E-Mail Removed)lid

Keith Thompson
Guest
Posts: n/a

 08-20-2005
(E-Mail Removed) writes:
> I am doing embedded programming and coding using NIOS processor.
> I am reading a 32 bit value from a register and storing it in a 32 bit
> data type.
> for e.g.
>
> alt_u32 gain = 0x42ED4000;

But that's not reading a value from a register; you're specifying the
literal value in your program.

> [alt_u32 is a data type provided by NIOS]

Ok, so alt_u32 is a 32-bit unsigned integer type, and you have some
mechanism to read a 32-bit value into an object of that type.

What you're describing has nothing to do with hexadecimal.
Hexadecimal is just one of a number of ways the value can be
displayed, but it's just a 32-bit integer.

> This is the value, which I need to convert it into float. Simply
> typecasting it into float doesn't seem to yield the correct value of
> float. The above code which uses scanf does. Hence posted the above
> question.

Casting an integer value to type float does a numeric conversion. You
want (I think) to re-interpret the alt_u32 value as a value of type
float; same bits, different meaning.

I think you want to do something like this:

alt_u32 gain = get_value_from_register();
float real_gain = *(float*)&gain;

This takes the address of gain, converts it from pointer-to-alt_u32 to
pointer-to-float, and dereferences the converted pointer.

This is higtly non-portable, but it sounds like your code needs to be
system-specific anyway, so that's probably not a fatal problem.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.