Break float into 4 bytes 
Author Message
 Break float into 4 bytes

Hi, I'm looking for a way to take a 4 byte float variable and assign
each of it's four bytes to four byte length variables(unsigned char).  I
would also like to be able to reconstruct the float later in the program
using these four variables.  Can anyone tell me how to do this?

I've seen this for int's:

unsigned char lobyte, hibyte;
int value = 1000;

lobyte = value & 0xff;
hibyte = (value & 0xff00) >> 8;

Thanks a lot, Bill
--



Wed, 06 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

wrote in comp.lang.c.moderated:

Quote:
> Hi, I'm looking for a way to take a 4 byte float variable and assign
> each of it's four bytes to four byte length variables(unsigned char).  I
> would also like to be able to reconstruct the float later in the program
> using these four variables.  Can anyone tell me how to do this?

> I've seen this for int's:

> unsigned char lobyte, hibyte;
> int value = 1000;

> lobyte = value & 0xff;
> hibyte = (value & 0xff00) >> 8;

> Thanks a lot, Bill

Can't do this with floating point types.  There are a few methods:

1.  Use a union...

   union uc_and_f { float f; unsigned char uc[sizeof(float)]; };

2.  Use memcpy()...

   float f; unsigned char uc[sizeof(float)];
   /* assign to f */
   memcpy(uc, &f, sizeof(float));

Jack Klein
--
Home: http://home.att.net/~jackklein
--



Thu, 07 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

Quote:

> Hi, I'm looking for a way to take a 4 byte float variable and assign
> each of it's four bytes to four byte length variables(unsigned char).  I
> would also like to be able to reconstruct the float later in the program
> using these four variables.  Can anyone tell me how to do this?

float twopi = 6.28f;
float f;
unsigned char a, b, c, d;

a = ((unsigned char *)&twopi)[0];
b = ((unsigned char *)&twopi)[1];
c = ((unsigned char *)&twopi)[2];
d = ((unsigned char *)&twopi)[3];

((unsigned char *)&f)[0] = a;
((unsigned char *)&f)[1] = b;
((unsigned char *)&f)[2] = c;
((unsigned char *)&f)[3] = d;

/* here, f is the exact bit-pattern (thus equal to) twopi. */
...

Quote:

> I've seen this for int's:

> unsigned char lobyte, hibyte;
> int value = 1000;

> lobyte = value & 0xff;
> hibyte = (value & 0xff00) >> 8;

> Thanks a lot, Bill
> --


--
When I was a boy of four{*filter*}, my father was so ignorant I could hardly
stand to have the old man around.  But when I got to be twenty-one, I was
astonished at how much the old man had learned in seven years. -Mark Twain

--



Thu, 07 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes
Your code for 'int's is non-portable (what about 32-bit ints? 64-bit?). Any
similar solution for 'float's would be non-portable, as well, because the
standard does not mandate the size of a float (it is quite legal to have
float == double == long double).

A _very_ non-portable solution would be:

union float_char {
    float f;
    unsigned char ch[sizeof(float)];

Quote:
};

store the float in f, then read the characters from ch.

I leave the discovery of all the ways in which this code is non-portable as
an exercise for the student...

A better solution is to store floating-point variables as text. This will
ensure that they can be read on any machine supporting your machine's
character set, and conversion between character sets is _much_ easier than
conversion between floating-point formats!

--
Daniel Pfeffer
--------------
Remove 'nospam' from my address in order to contact me directly


Quote:
> Hi, I'm looking for a way to take a 4 byte float variable and assign
> each of it's four bytes to four byte length variables(unsigned char).  I
> would also like to be able to reconstruct the float later in the program
> using these four variables.  Can anyone tell me how to do this?

> I've seen this for int's:

> unsigned char lobyte, hibyte;
> int value = 1000;

> lobyte = value & 0xff;
> hibyte = (value & 0xff00) >> 8;

> Thanks a lot, Bill
> --


--



Thu, 07 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes
union splitfloat
  {
  float f;
  unsigned char b[4];
  };

You could then have some code as follows:

int main( void )
  {
  union splitfloat sf;
  unsigned char a, b, c, d;

  sf.f = 2.3;

  a = sf.b[0];
  b = sf.b[1];
  c = sf.b[2];
  d = sf.b[3];

  /* other code */
  return 0;

Quote:
}

Of course, it's up to you to remember the ordering to recover the
original float.

Hope this helps,
JD

Quote:

> Hi, I'm looking for a way to take a 4 byte float variable and assign
> each of it's four bytes to four byte length variables(unsigned char).  I
> would also like to be able to reconstruct the float later in the program
> using these four variables.  Can anyone tell me how to do this?

> I've seen this for int's:

> unsigned char lobyte, hibyte;
> int value = 1000;

> lobyte = value & 0xff;
> hibyte = (value & 0xff00) >> 8;

> Thanks a lot, Bill
> --


--



Thu, 07 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

Quote:

>  I
> would also like to be able to reconstruct the float later in the program
> using these four variables.

> A _very_ non-portable solution would be:

> union float_char {
>     float f;
>     unsigned char ch[sizeof(float)];
> };

> store the float in f, then read the characters from ch.

I'm surprised that the most portable code in this thread (at time of
writing) is labelled as non-portable. For what the original poster
wanted (to split a float up into chars for later use in the same
program, presumably the same program execution) this is perfectably
portable. It will work every time, on every machine. What won't work is
writing the data to a file for being read back in later, by a different
instance of the program. And even that is perfectably portable if what
you want is a temporary file that is not intended to be safe between
versions of your program.

Just because something is low-level doesn't mean it's non-portable. Your
union, by merit of the sizeof(float), addresses the portability issue.

Quite why Mr Pierce might want to do this is another matter ....

Jeremy Carroll

---

Personal message, not the opinion of my employer.

--



Fri, 08 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes
I _did_ assume that the data must be passed to another program.
Deconstructing and reconstructing a 'float' inside the same program is
obviously OK.

--
Daniel Pfeffer
--------------
Remove 'nospam' from my address in order to contact me directly


Quote:


> >  I
> > would also like to be able to reconstruct the float later in the program
> > using these four variables.


> > A _very_ non-portable solution would be:

> > union float_char {
> >     float f;
> >     unsigned char ch[sizeof(float)];
> > };

> > store the float in f, then read the characters from ch.

> I'm surprised that the most portable code in this thread (at time of
> writing) is labelled as non-portable. For what the original poster
> wanted (to split a float up into chars for later use in the same
> program, presumably the same program execution) this is perfectably
> portable. It will work every time, on every machine. What won't work is
> writing the data to a file for being read back in later, by a different
> instance of the program. And even that is perfectably portable if what
> you want is a temporary file that is not intended to be safe between
> versions of your program.

> Just because something is low-level doesn't mean it's non-portable. Your
> union, by merit of the sizeof(float), addresses the portability issue.

> Quite why Mr Pierce might want to do this is another matter ....

> Jeremy Carroll

> ---

> Personal message, not the opinion of my employer.

> --


--



Sat, 09 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

Quote:


> >  I
> > would also like to be able to reconstruct the float later in the program
> > using these four variables.


> > A _very_ non-portable solution would be:

> > union float_char {
> >     float f;
> >     unsigned char ch[sizeof(float)];
> > };

> > store the float in f, then read the characters from ch.

> I'm surprised that the most portable code in this thread (at time of
> writing) is labelled as non-portable.

I thought that writing something into a union as one type and reading
it out as another provoked undefined behaviour?

Robert
--
The above are my opinions,
 and my opinions only.
--



Sat, 09 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes


Quote:
>I thought that writing something into a union as one type and reading
>it out as another provoked undefined behaviour?

There is a specific exception for unsigned char as this represents raw
memory.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Sun, 10 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

Quote:
Robert Pluim writes:
> I thought that writing something into a union as one type and reading
> it out as another provoked undefined behaviour?

No, it's implementation-defined.  In the current standard, that's
specified in section 6.3.2.3.
--
Mark Brader           | At any rate, C++ != C.  Actually, the value of
Toronto               | the expression "C++ != C" is [undefined].

My text in this article is in the public domain.
--



Sun, 10 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes


Quote:


> >I thought that writing something into a union as one type and reading
> >it out as another provoked undefined behaviour?

> There is a specific exception for unsigned char as this represents raw
> memory.

Could someone give me references for Robert's original comment
(which I've always believed to be true), and Francis's exception
(which was news to me), please. I can't find either explicitly
stated in the standard, at least not by looking up 'union' in
the index; I guess they're implied by other things. ANSI section
numbers would be preferred over ISO!

Many Thanks,
                 jjf

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
--



Wed, 13 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

Quote:
Robert Pluim writes:
>>> I thought that writing something into a union as one type and reading
>>> it out as another provoked undefined behaviour?
Francis Glassborow writes:
>> There is a specific exception for unsigned char as this represents raw
>> memory.
J.J. Farrell writes:
> Could someone give me references for Robert's original comment
> (which I've always believed to be true),

Again, it's false; the behavior is implementation-defined.  Original
ANSI section 3.3.2.3 (now 6.3.2.3), semantics, third paragraph.

Quote:
> and Francis's exception (which was news to me), please.

The rule Francis is thinking of actually says that you can access any
object using an lvalue of a character type (not just unsigned char).
This is the last thing in ANSI section 3.3 (now 6.3).  For example,
this allows you to write:

        extern int i;
        char *cp, *bp;
        for (bp = cp = (char *) &i; cp < bp + sizeof(int); ++cp)
                func (*cp);
        /* code not tested before posting */

to access the successive bytes of an int as chars.

Quote:
> I can't find either explicitly stated in the standard, at least not
> by looking up 'union' in the index...

For 3.3.2.3 you have to look under "structure/union member operator .".
The rule in 3.3 does not partain specifically to unions, and I can't see
any index entry more specific than "expressions" that points to it.

Quote:
> ANSI section numbers would be preferred over ISO!

Done.
--
Mark Brader                     "How many pessimists end up by desiring
Toronto                          the things they fear, in order to prove

My text in this article is in the public domain.
--



Wed, 13 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

Quote:

> Robert Pluim writes:
> >>> I thought that writing something into a union as one type and reading
> >>> it out as another provoked undefined behaviour?

> Francis Glassborow writes:
> >> There is a specific exception for unsigned char as this represents raw
> >> memory.

> J.J. Farrell writes:
> > Could someone give me references for Robert's original comment
> > (which I've always believed to be true),

> Again, it's false; the behavior is implementation-defined.  Original
> ANSI section 3.3.2.3 (now 6.3.2.3), semantics, third paragraph.

Perhaps I'm just being dense (it wouldn't be the first time), but the
first two statements of this paragraph appear to contradict each other
(unless we're arguing about the difference between undefined and
implementation-defined again, which is a subtlety I'd rather not get
involved with).

Robert
--
The above are my opinions,
 and my opinions only.
--



Sat, 16 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes

Quote:


> > Robert Pluim writes:
> > >>> I thought that writing something into a union as one type and reading
> > >>> it out as another provoked undefined behaviour?

> > Francis Glassborow writes:
> > >> There is a specific exception for unsigned char as this represents raw
> > >> memory.

> > J.J. Farrell writes:
> > > Could someone give me references for Robert's original comment
> > > (which I've always believed to be true),

> > Again, it's false; the behavior is implementation-defined.  Original
> > ANSI section 3.3.2.3 (now 6.3.2.3), semantics, third paragraph.

> Perhaps I'm just being dense (it wouldn't be the first time), but the
> first two statements of this paragraph appear to contradict each other
> (unless we're arguing about the difference between undefined and
> implementation-defined again, which is a subtlety I'd rather not get
> involved with).

Ok, I was being dense. There is no contradiction (thanks for the
explanation, Mark).

Robert
--
The above are my opinions,
 and my opinions only.
--



Sun, 17 Feb 2002 03:00:00 GMT  
 Break float into 4 bytes


Quote:
> Robert Pluim writes:
> >>> I thought that writing something into a union as one type and
> >>> reading it out as another provoked undefined behaviour?

> Francis Glassborow writes:
> >> There is a specific exception for unsigned char as this
> >> represents raw memory.

> J.J. Farrell writes:
> > Could someone give me references for Robert's original comment
> > (which I've always believed to be true),

> Again, it's false; the behavior is implementation-defined.  Original
> ANSI section 3.3.2.3 (now 6.3.2.3), semantics, third paragraph.

> > and Francis's exception (which was news to me), please.

> The rule Francis is thinking of actually says that you can access any
> object using an lvalue of a character type (not just unsigned char).
> This is the last thing in ANSI section 3.3 (now 6.3).  For example,
> this allows you to write:

>    extern int i;
>    char *cp, *bp;
>    for (bp = cp = (char *) &i; cp < bp + sizeof(int); ++cp)
>            func (*cp);
>    /* code not tested before posting */

> to access the successive bytes of an int as chars.

Thanks, Mark. I'm still left a little confused. Consider:

union float_char {
   float f;
   unsigned char ch[sizeof(float)];

Quote:
};

3.3.2.3 explicitly states that writing to f and reading from
ch results in implementation-defined behaviour, since they
are different members of the same union. I can't see how the
general 'access allowed through a char' exception overrides
this explicit statement.

It seems to me that using the union approach to access a float
as chars relies on implementation-defined behaviour, whereas
taking the address of the float, casting it to a character
pointer, and using this pointer to walk through the float as
chars is fully defined by the language. Is this correct, or
am I missing something?

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
--



Sun, 17 Feb 2002 03:00:00 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. lint on Altos 2000 is BROKE BROKE BROKE!

2. Extract bytes from a float

3. float byte swapping ?

4. Surprise? 4-byte float and the newbie programmer

5. Question: Correct process to byte-swap floats?

6. IEEE conversion: bytes into floating point number...

7. 8-byte double long integer to floating point?

8. How to convert between float and BYTE

9. IEEE conversion: bytes into floating point number...

10. bytes to float conversion

11. How to convert between float and BYTE

12. convert floating-point value to network byte-order

 

 
Powered by phpBB® Forum Software