public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: Casting and Optimization Flags
@ 2002-12-11  9:06 Hillel (Sabba) Markowitz
  0 siblings, 0 replies; 6+ messages in thread
From: Hillel (Sabba) Markowitz @ 2002-12-11  9:06 UTC (permalink / raw)
  To: GCC Help; +Cc: c.law

-------------------- Original Message ----------------------------------
From: Colin Law <c dot law at elec dot gla dot ac dot uk>
     To: Rob Shearer <Rob dot Shearer at networkinference dot com>, eljay at 
adobe dot com
     Cc: gcc-help at gcc dot gnu dot org
     Date: Wed, 11 Dec 2002 13:39:38 +0000
     Subject: Re: Casting and Optimization Flags
     References: 
<3BE4D3F0FB726240966DEF40418472B502EC6F@NI-LON-SERVER1.ad.networkinference.com
>





        casting floats to integers does not round; it truncates

Thanks for the replies. Why was this behaviour more (only!) obvious when I 
used the compiler optimization flags? Had I not tried this, I would be quite 
oblivious to the problem, which could have been very
difficult to track down futher down the line.

Thanks for the bit twiddling hack link Eljay, some of these will do exactly 
what I'm looking for.

~Colin.
---------------------- End Original Message --------------------------------

On some platforms there is a difference in accuracy between the memory and the 
register arithmetic for floating point numbers.  When you ran without 
optimization, the values were stored in memory along the way.  Under 
optimization, they happened to jus be kept in registers with enough of a 
difference to trigger the error that you saw.

-- 
Said the fox to the fish, "Join me ashore".
 The fish are the Jews, Torah is our water

Hillel (Sabba) Markowitz - sabbahem@bcpl.net

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Casting and Optimization Flags
  2002-12-11  4:43 Rob Shearer
  2002-12-11  5:47 ` Colin Law
@ 2002-12-11 11:14 ` Joseph D. Wagner
  1 sibling, 0 replies; 6+ messages in thread
From: Joseph D. Wagner @ 2002-12-11 11:14 UTC (permalink / raw)
  To: 'Rob Shearer', 'Colin Law', gcc-help

> casting floats to integers does not round; it truncates
> 
> To round, simply add 0.5 to your float.

GOOD GRIEF NO! DON'T DO THAT! That will just compound the problem.

Use:
ceil(x) - rounds up to nearest int
floor(x) - rounds down to nearest int

Requires:
#include <cmath>

Joseph Wagner

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Casting and Optimization Flags
  2002-12-11  4:43 Rob Shearer
@ 2002-12-11  5:47 ` Colin Law
  2002-12-11 11:14 ` Joseph D. Wagner
  1 sibling, 0 replies; 6+ messages in thread
From: Colin Law @ 2002-12-11  5:47 UTC (permalink / raw)
  To: Rob Shearer, eljay; +Cc: gcc-help

>
>
>casting floats to integers does not round; it truncates
>  
>
Thanks for the replies.  Why was this behaviour more (only!) obvious 
when I used the compiler optimization flags? Had I not tried this, I 
would be quite oblivious to the problem, which could have been very 
difficult to track down futher down the line.

Thanks for the bit twiddling hack link Eljay, some of these will do 
exactly what I'm looking for.

~Colin.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Casting and Optimization Flags
  2002-12-11  4:31 Colin Law
@ 2002-12-11  5:24 ` John Love-Jensen
  0 siblings, 0 replies; 6+ messages in thread
From: John Love-Jensen @ 2002-12-11  5:24 UTC (permalink / raw)
  To: Colin Law, gcc-help

Hi Colin,

Floating point numbers are not exact numbers, and slight rounding and/or
truncation issues should be expected.

There are much better (i.e., exacting) algorithms to calculate your desired
value width.  On modern architectures with 1-cycle FPU log10 and division,
the performance will be similar.  On slightly older architectures, these
algorithms are more efficient.

Check out this excellent Stanford page of Bit Twiddling Hacks, kudos to Sean
Eron Anderson.  <http://graphics.stanford.edu/~seander/bithacks.html>

In particular, the "Find the log base 2 of an N-bit integer in O(lg(N))
operations".  Or perhaps the "Round up to the next highest power of 2" is
more suited to your needs.

Note:  I'd avoid the "Find integer log base 2 of a 32-bit IEEE float", since
the algorithm presumes (and relies upon) the IEEE layout in memory.  But
that's because I like to write platform agnostic C++ code.

--Eljay

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Casting and Optimization Flags
@ 2002-12-11  4:43 Rob Shearer
  2002-12-11  5:47 ` Colin Law
  2002-12-11 11:14 ` Joseph D. Wagner
  0 siblings, 2 replies; 6+ messages in thread
From: Rob Shearer @ 2002-12-11  4:43 UTC (permalink / raw)
  To: Colin Law, gcc-help

casting floats to integers does not round; it truncates

To round, simply add 0.5 to your float.

Obviously I don't know what you're trying to do, but there look to be a
number of significant ways to improve the code you've outlined.
Explicitly casting an integer literal is never necessary; just create
the type you want: 2 may be an integer, but 2.0 is a double, 2.0f a
float, and 2.0l (that's an el, not a one) a long double. More to the
point, if all you're doing is finding the log in base 2 then that is
just the highest bit that's set and there are many much more efficient
ways to find this than going through floating point math.

> -----Original Message-----
> From: Colin Law [mailto:c.law@elec.gla.ac.uk] 
> Sent: 11 December 2002 12:24
> To: gcc-help@gcc.gnu.org
> Subject: Casting and Optimization Flags
> 
> 
> Hello,
> 
> I am having trouble with a section of code that runs fine 
> when compiled 
> with no optimization flags, however when I add 
> optimization,flags, I get 
> different results.
> 
> In the middle of a for loop, and a fairly heavily recursive 
> procedure i 
> has this;
> 
> double d = (std::log10(static_cast<double>(width))) / 
> (std::log10(static_cast<double>(2))) ;
> unsigned int level = static_cast<unsigned int>(d) ;
> 
> Which will (should) always return me an integer value for my 
> values of 
> width (always 2^n values). When i sprinf both d and level i 
> can see that 
> the value is cast fine with no optimization, however when i 
> compile with 
> -O2 or -O1, after the cast the int doesn't always match the double, 
> casting double 3 to an unsigned int =2 !!!
> 
> It appears that my double value is so close to an int that it is 
> regarded as a whole number,however during the cast the decimal values 
> are simpley chopped so 2.9999..... cast to unsinged int is 2. sprinf 
> (%.20f) tells me the value of d is  3.0000... not 2.9999...
> 
> I am unable to reprodude this problem in a trivial case which 
> suggests 
> it is something i am missing in the main code, however, as i am 
> assigning to new variables, i cannot see where this could possible be.
> 
> If I use long double instead of double during the calculation. then 
> cast, I appear to get the correct results even with optimization!
> 
> Any suggestions as to what is causing this ??
> I am using g++-3.2 and am compiling the above as part of a shared 
> library with -fPIC -Wall -O2 if thats any help.
> 
> Regards
> ~Colin.
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Casting and Optimization Flags
@ 2002-12-11  4:31 Colin Law
  2002-12-11  5:24 ` John Love-Jensen
  0 siblings, 1 reply; 6+ messages in thread
From: Colin Law @ 2002-12-11  4:31 UTC (permalink / raw)
  To: gcc-help

Hello,

I am having trouble with a section of code that runs fine when compiled 
with no optimization flags, however when I add optimization,flags, I get 
different results.

In the middle of a for loop, and a fairly heavily recursive procedure i 
has this;

double d = (std::log10(static_cast<double>(width))) / 
(std::log10(static_cast<double>(2))) ;
unsigned int level = static_cast<unsigned int>(d) ;

Which will (should) always return me an integer value for my values of 
width (always 2^n values). When i sprinf both d and level i can see that 
the value is cast fine with no optimization, however when i compile with 
-O2 or -O1, after the cast the int doesn't always match the double, 
casting double 3 to an unsigned int =2 !!!

It appears that my double value is so close to an int that it is 
regarded as a whole number,however during the cast the decimal values 
are simpley chopped so 2.9999..... cast to unsinged int is 2. sprinf 
(%.20f) tells me the value of d is  3.0000... not 2.9999...

I am unable to reprodude this problem in a trivial case which suggests 
it is something i am missing in the main code, however, as i am 
assigning to new variables, i cannot see where this could possible be.

If I use long double instead of double during the calculation. then 
cast, I appear to get the correct results even with optimization!

Any suggestions as to what is causing this ??
I am using g++-3.2 and am compiling the above as part of a shared 
library with -fPIC -Wall -O2 if thats any help.

Regards
~Colin.



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2002-12-11 19:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-11  9:06 Casting and Optimization Flags Hillel (Sabba) Markowitz
  -- strict thread matches above, loose matches on Subject: below --
2002-12-11  4:43 Rob Shearer
2002-12-11  5:47 ` Colin Law
2002-12-11 11:14 ` Joseph D. Wagner
2002-12-11  4:31 Colin Law
2002-12-11  5:24 ` John Love-Jensen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).