Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » C++

interpreting float data as ints

 
Jump to:  
 
Guest
PostPosted: Wed Sep 03, 2008 8:38 am    Post subject: interpreting float data as ints
       
Hello,

I am wondering if this program has a defined output and if yes what
the output should be. I would it expect the program to print 0.123456
but I get completely bogus values instead. I am running GCC 4.3.1 and
the compiler's ABI requires the parameter for operator<< to be passed
on the FPU stack. In the generated code, a bogus value is first copied
from a memory location onto the FPU stack, then the memory location is
initialized with the correct value of 0.123456f. To get the expected
result, these two operations have to be reversed. Does anyone have an
insight on what is going on or is this simply an optimizer bug?

-Marek

#include <iostream>

int write
(
float value
)
{
int i = *reinterpret_cast<int *>( &value );
return i;
}

float read
(
int value
)
{
float f = *reinterpret_cast<float *>( &value );
return f;
}

int main()
{
const float value = 0.123456f;
std::cout << read( write( value ) );
}

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Thomas Richter
PostPosted: Wed Sep 03, 2008 8:58 pm    Post subject: Re: interpreting float data as ints
       
marek.vondrak@gmail.com schrieb:

Quote:
I am wondering if this program has a defined output

No, it doesn't. First of all, ints or floats might have trap values,
which could interrupt your program execution. Second, an int need not
to be wide enough to represent all possible float bit patterns.

Quote:
and if yes what
the output should be. I would it expect the program to print 0.123456
but I get completely bogus values instead. I am running GCC 4.3.1 and
the compiler's ABI requires the parameter for operator<< to be passed
on the FPU stack. In the generated code, a bogus value is first copied
from a memory location onto the FPU stack, then the memory location is
initialized with the correct value of 0.123456f. To get the expected
result, these two operations have to be reversed. Does anyone have an
insight on what is going on or is this simply an optimizer bug?

It might be an optimizer bug given your description, but even with that fixed
the program is not well-defined by the C++ standard.

Quote:
#include <iostream

int write
(
float value
)
{
int i = *reinterpret_cast<int *>( &value );
return i;
}

float read
(
int value
)
{
float f = *reinterpret_cast<float *>( &value );
return f;
}

int main()
{
const float value = 0.123456f;
std::cout << read( write( value ) );
}

So long,
Thomas


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
gpderetta
PostPosted: Thu Sep 04, 2008 1:46 am    Post subject: Re: interpreting float data as ints
       
On Sep 3, 10:38 am, marek.vond...@gmail.com wrote:
Quote:
Hello,

I am wondering if this program has a defined output and if yes what
the output should be. I would it expect the program to print 0.123456
but I get completely bogus values instead. I am running GCC 4.3.1 and
the compiler's ABI requires the parameter for operator<< to be passed
on the FPU stack. In the generated code, a bogus value is first copied
from a memory location onto the FPU stack, then the memory location is
initialized with the correct value of 0.123456f. To get the expected
result, these two operations have to be reversed. Does anyone have an
insight on what is going on or is this simply an optimizer bug?

-Marek

#include <iostream

int write
(
float value
)
{
int i = *reinterpret_cast<int *>( &value );
return i;

}

float read
(
int value
)
{
float f = *reinterpret_cast<float *>( &value );
return f;

}

int main()
{
const float value = 0.123456f;
std::cout << read( write( value ) );

}


No, this is not an optimizer bug. You are reading an int type from a
float object, which is undefined behavior. In general, save for a
couple of exceptions, a compiler is free to reorder read and writes to
memory locations which do not have compatible types, without having to
prove first that the locations do not alias each other (Google for
type based alias analysis for more informations).

--
gpd


[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Guest
PostPosted: Thu Sep 04, 2008 4:24 am    Post subject: Re: interpreting float data as ints
       
Quote:
No, this is not an optimizer bug. You are reading an int type from a
float object, which is undefined behavior. In general, save for a
couple of exceptions, a compiler is free to reorder read and writes to
memory locations which do not have compatible types, without having to
prove first that the locations do not alias each other (Google for
type based alias analysis for more informations).

Okay, so what would be the appropriate way of accessing individual
bits of a float on i386? GCC's manual suggest that unions should be
used for this purpose (and that indeed fixes my problem).
-Marek

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Seungbeom Kim
PostPosted: Thu Sep 04, 2008 9:28 am    Post subject: Re: interpreting float data as ints
       
marek.vondrak@gmail.com wrote:
Quote:
No, this is not an optimizer bug. You are reading an int type from a
float object, which is undefined behavior. In general, save for a
couple of exceptions, a compiler is free to reorder read and writes to
memory locations which do not have compatible types, without having to
prove first that the locations do not alias each other (Google for
type based alias analysis for more informations).

Okay, so what would be the appropriate way of accessing individual
bits of a float on i386? GCC's manual suggest that unions should be
used for this purpose (and that indeed fixes my problem).

You can access the stored value of an object through an lvalue of
char or unsigned char type (3.10/15). Moreover, you can copy the
underlying bytes making up the object into an array of char or
unsigned char (through memcpy) if the object is of a POD type (3.9/2).

--
Seungbeom Kim

[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Thomas Richter
PostPosted: Thu Sep 04, 2008 9:29 am    Post subject: Re: interpreting float data as ints
       
marek.vondrak@gmail.com schrieb:
Quote:
No, this is not an optimizer bug. You are reading an int type from a
float object, which is undefined behavior. In general, save for a
couple of exceptions, a compiler is free to reorder read and writes to
memory locations which do not have compatible types, without having to
prove first that the locations do not alias each other (Google for
type based alias analysis for more informations).

Okay, so what would be the appropriate way of accessing individual
bits of a float on i386? GCC's manual suggest that unions should be
used for this purpose (and that indeed fixes my problem).

This is one way to do it - another is to use the
__attribute((may_alias)) extension of gcc, as in:

typedef float __attribute((may_alias)) float_aliased;

and use this type for passing values into and out of your converter
functions.

Note that this solution (as the one with the union) is non-portable.

So long,
Thomas

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
gpderetta
PostPosted: Thu Sep 04, 2008 7:38 pm    Post subject: Re: interpreting float data as ints
       
On Sep 4, 11:28 am, Seungbeom Kim <musip...@bawi.org> wrote:
Quote:
marek.vond...@gmail.com wrote:
No, this is not an optimizer bug. You are reading an int type from a
float object, which is undefined behavior. In general, save for a
couple of exceptions, a compiler is free to reorder read and writes to
memory locations which do not have compatible types, without having to
prove first that the locations do not alias each other (Google for
type based alias analysis for more informations).

Okay, so what would be the appropriate way of accessing individual
bits of a float on i386? GCC's manual suggest that unions should be
used for this purpose (and that indeed fixes my problem).

Note that the union is also technically UB. GCC explicitly supports it
as an extension, and so do other compilers.

Quote:

You can access the stored value of an object through an lvalue of
char or unsigned char type (3.10/15). Moreover, you can copy the
underlying bytes making up the object into an array of char or
unsigned char (through memcpy) if the object is of a POD type (3.9/2).


In particular, at least on GCC, memcpy, when used for type punning of
primitive types, generates optimal code.

--
gpd



--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Marco Manfredini
PostPosted: Fri Sep 05, 2008 4:21 am    Post subject: Re: interpreting float data as ints
       
marek.vondrak@gmail.com wrote:
Quote:
Hello,

I am wondering if this program has a defined output and if yes what
the output should be. I would it expect the program to print 0.123456
but I get completely bogus values instead. I am running GCC 4.3.1 and
the compiler's ABI requires the parameter for operator<< to be passed
on the FPU stack. In the generated code, a bogus value is first copied
from a memory location onto the FPU stack, then the memory location is
initialized with the correct value of 0.123456f. To get the expected
result, these two operations have to be reversed. Does anyone have an
insight on what is going on or is this simply an optimizer bug?

It's not an optimizer bug. On all optimization levels >=O2, gcc enables
-fstrict-aliasing, which basically means, that gcc now assumes that a
pointer does not alias with an pointer of a sufficiently different type.
You should get a warning with -Wall that type punning breaks things.

Look up -fstruct-aliasing in the gcc manual and read the suggestions how
to do type punning with unions.


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Page 1 of 1 .:.

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

Targus FII 15.4? Hard Shell - sztywna torba do not banery gry i zabawy egypt Portal Miasteczko dolnoslaskie