My lack of understanding of casting is getting me down, help appreciated...

Started by
7 comments, last by pragma Fury 18 years, 10 months ago
Ok, I have this line.

int LeftEdge = static_cast<int>((1024.0f - (FirstNameWidth * ReductionRatio))/2.0f);

ReductionRatio is a float. FirstNameWidth is an int. What I want to happen is that everything works in float form and then the answer is truncated into an int which is assigned to LeftEdge. So FirstNameWidth * ReductionRatio is subtracted from 1024.0f and then the result is divided by two, but I keep getting like 4365265733. Which is obviously not right. Any help? Thanks, Mark Coleman
Advertisement
There are various promotion/precedence rules governing how a mixed-type expression is interpretted. I can never remember them, and always explicitly add extra parenthesis [smile]. Check a decent C/C++ book for the rules if you're interested.

From looking at your code, the part:

FirstNameWidth * ReductionRatio

is basically a int * float, because you're not specifying a cast here, the compiler will be trying to work out what to do based on the aforementioned rules.

Try casting the int to a float:

static_cast<float>( FirstNameWidth ) * ReductionRatio

Thus, your whole line should be:

int LeftEdge = static_cast<int>((1024.0f - (static_cast<float>(FirstNameWidth) * ReductionRatio))/2.0f);

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by Endurion
Shouldn't it be reinterpret_cast in this case as static_cast will perform a bitwise cast?

reinterpret_cast<>() just takes the (for example) 32bits of an integer and makes them a float - with no other considerations.

static_cast<>() is effectively the same as classic C-style (type)expr casting.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Static cast is fine.

I just cut and pasted your code your code, then ran it with ReductionRatio=0.8 and FirstNameWidth=2.

int LeftEdge was then 511, which is correct.

(1024 - (2*0.8))/2 =
(1024 - 1.6)/2 =
1022.4/2 = 511.2 = 511 (int)


What numbers for ReductionRatio and FirstNameWidth are you having trouble with?
Cheers Jack, although I tracked my problem down..!

I had not initialised FirstNameWidth before it was used.

I am having a terrible day ;(

Mark Coleman
Good job :)

Try replacing the /2 with a *0.5. It'll be a teensy bit faster :) Probably not enough to notice :)
Quote:Original post by pragma Fury
Good job :)

Try replacing the /2 with a *0.5. It'll be a teensy bit faster :) Probably not enough to notice :)


If he is using a good optimizing compiler, shouldn't he leave it the way it is, since it will automatically be done anyway?
Quote:Original post by Sagar_Indurkhya
Quote:Original post by pragma Fury
Good job :)

Try replacing the /2 with a *0.5. It'll be a teensy bit faster :) Probably not enough to notice :)


If he is using a good optimizing compiler, shouldn't he leave it the way it is, since it will automatically be done anyway?

Not that I'm 100% sure about this, but a good compiler should NOT do that. The compiler should only make optimizations as long as the behaviour is not changed. Changing the division to a multiplication with the inverse is mathematically the same thing, but due to precision errors, changing operation at compile time could potentially change the result aswell. Maybe not by much, but if you have done a rigorous analysis of how the precision propagates through the code, and you know how to deal with it, this change in behaviour could produce unexpected results as the error is no longer what you expected it to be.

Newer compilers seems to have some options to enable optimizations like this, where more effort is put on making the code more effective, while sacrificing the ability to precicely control the precision errors.

So I would expect the compiler to not do it.

edit: Just remembered I had this article in my bookmarks. VERY interesting article on floating point optimizations.
Quote:Original post by Sagar_Indurkhya
Quote:Original post by pragma Fury
Good job :)

Try replacing the /2 with a *0.5. It'll be a teensy bit faster :) Probably not enough to notice :)


If he is using a good optimizing compiler, shouldn't he leave it the way it is, since it will automatically be done anyway?


If you look at the asm generated by the VC compiler (even with a release build) you will see that /2 results in a fdiv operation, whereas *0.5 results in fmul

Brother Bob makes a valid point about precision errors. Though, unless you're running some high-precision physics simulations, you likely won't notice the difference. But, the compiler has no clue what you're trying to make, so it's not going to make any assumptions.

This topic is closed to new replies.

Advertisement