Author |
Message |
William Pierc #1 / 17
|
 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 |
|
 |
Jack Kle #2 / 17
|
 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 |
|
 |
Tommy Knowlto #3 / 17
|
 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 |
|
 |
Daniel M. Pfeffe #4 / 17
|
 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 |
|
 |
Michael K. Danie #5 / 17
|
 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 |
|
 |
Jeremy Carrol #6 / 17
|
 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 |
|
 |
Daniel M. Pfeffe #7 / 17
|
 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 |
|
 |
Robert Plui #8 / 17
|
 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 |
|
 |
Francis Glassboro #9 / 17
|
 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 |
|
 |
Mark Brad #10 / 17
|
 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 |
|
 |
J. J. Farrel #11 / 17
|
 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 |
|
 |
Mark Brad #12 / 17
|
 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 |
|
 |
Robert Plui #13 / 17
|
 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 |
|
 |
Robert Plui #14 / 17
|
 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 |
|
 |
J. J. Farrel #15 / 17
|
 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 |
|
|
Page 1 of 2
|
[ 17 post ] |
|
Go to page:
[1]
[2] |
|