Skip to main content
GameDev.net gamedev.net
🔒 Locked

Double or float in just one change

Started by Floating Jul 1, 2004 at 3:45 AM 17 replies 2.5k views
Original Post
Floating
Floating
Hi, I organized my code to later be able to select my prefered type (float or double) by using a "#define real float". Now if I call a function f taking as argument a "real" like: f(realValue*1.28); The compiler gives me a warning "warning C4244: 'argument' : conversion from 'double' to 'float', possible loss of data". However if my real is defined as double, I don't get any warnings. How would you go about removing warnings for both configurations of real (float or double)? (I could write "f(realValue*1.28f)" but thenmy constant gets rounded to a float constant...) Thanks :)
Koen
Koen
maybe f(some_value * static_cast(1.28))?
(btw: wouldn't it be safer to use a typedef instead of a #define?)
Qw3r7yU10p!
Qw3r7yU10p!
typedef float real;//typedef double real;//change with above if you wishreal to_real(double d) {    return real(d);}real to_real(float f) {    return real(f);}void f(real value) {}int main() {    real realValue = to_real(1.5);    f(realValue * to_real(1.28));}


All this makes me think you should really encapsulate it in a type which takes floats or doubles in the constructor.
class Real {public:    Real(float)    Real(double)    //operator* etc.};
DigitalDelusion
DigitalDelusion
here's another solution, maybe not as pretty but it silences the compiler and works quite wonderfully.

typedef float real;instead of: foo( realValue * 1.28);//the constant will be a double warning if real is floatdo: foo( realValue * real(1.28));//no warning and the constant get the correct type from the get go.it also works if you do like this: foo( realValue * real(doubleValue)); //no warning even if real is float


HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
joanusdmentia
joanusdmentia
Or you could just ignore the warning, since if you've chosen to go with float's then you should already know that they'll have enough precision for your needs.

You might also be able to disable the warning with a compiler flag.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o
Koen
Koen
Quote:
Original post by joanusdmentia
You might also be able to disable the warning with a compiler flag.

This could be dangerous: casts outside of your knowledge could be dangerous if precision is becoming an issue. Personally I prefer keeping the warnings and writing explicit casts (this should be avoided in the first place, I guess: input and output types should match).

PS: Petewood, do you think it's feasible to use a class for a floating point number? I don't know a lot about performance, but wouldn't this be a lot of overhead for what is gained?
Qw3r7yU10p!
Qw3r7yU10p!
Quote:
Original post by Koen
PS: Petewood, do you think it's feasible to use a class for a floating point number? I don't know a lot about performance, but wouldn't this be a lot of overhead for what is gained?


There would be overhead in typing the code, but no overhead in running it. I'm always interested in making things more explicit.

Using real(1.28) seems fine though as DigitalDelusion says. I think I'm over-doing it today.
joanusdmentia
joanusdmentia
Quote:
Original post by Koen
This could be dangerous: casts outside of your knowledge could be dangerous if precision is becoming an issue. Personally I prefer keeping the warnings and writing explicit casts (this should be avoided in the first place, I guess: input and output types should match).

In situations where you're dealing with a double variable being converted to float, then yes this could become an issue (although I wouldn't call it dangerous, this is going to cause calculation errors but it won't crash the app). But when dealing with constants like this though the compiler really should be smart enough to know that when you're passing 1.0 to a function that takes floats then the constant should be a float and not a double.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o
Floating
Floating
Thanks a lot for all the input! :)

I'll go with the casting "(real)1.28" even if it takes more typing
Etnu
Etnu
If you're worried about using doubles instead of floats for performance reasons (and need to switch back and forth) -- STOP.

All that casting back and forth is going to slow you down far more than the extra memory consumption of a double.

Your processor's FPU already operates on 80-bit numbers, regardless of if you're using half, single, or double precision floating point numbers.

if your code is already using mostly doubles...just make everything a double. The memory savings for floats really aren't worth the trouble of building seperate functions for everything.

If you are still heavily mixing floats and doubles, you could also just template your functions.
---------------------------Hello, and Welcome to some arbitrary temporal location in the space-time continuum.
iMalc
iMalc
Quote:
Original post by Etnu
If you're worried about using doubles instead of floats for performance reasons (and need to switch back and forth) -- STOP.

All that casting back and forth is going to slow you down far more than the extra memory consumption of a double.

Your processor's FPU already operates on 80-bit numbers, regardless of if you're using half, single, or double precision floating point numbers.

if your code is already using mostly doubles...just make everything a double. The memory savings for floats really aren't worth the trouble of building seperate functions for everything.

If you are still heavily mixing floats and doubles, you could also just template your functions.


I'm with the original poster. I have done the same thing in the past.

There is a reason for this kind of thing. disk space usage for one. There are good reasons for not wanting to hard code everything to double right away. You may not want to be stuck using doubles at the end of your project, and may want the option of using floats instead to save disk space for example. He is not talking about being able to use both in the same compilation, but chosing which is used for the entire project.

As for float speed vs double speed. Perhaps you could post some real benchmarks that prove that accessing twice the memory (or even twice the hard disk amount) is actually going to be faster. Any time I've measured it the results said otherwise.

On the contrary to your paragraph 4. The memory savings could be extrmely high if you have a very large amount of floating point data and it can be reduced by a factor of two.

Templating functions is not in itself going to solve the warning he is getting. Explicit casting (as another poster mentioned) is still going to be required.

What is needed is for someone to post the exact string for turning off this specific compiler warning in the code. what is the #pragma disable number?
Floating
Floating
Quote:
Original post by Etnu
If you're worried about using doubles instead of floats for performance reasons (and need to switch back and forth) -- STOP.

All that casting back and forth is going to slow you down far more than the extra memory consumption of a double.

Your processor's FPU already operates on 80-bit numbers, regardless of if you're using half, single, or double precision floating point numbers.

if your code is already using mostly doubles...just make everything a double. The memory savings for floats really aren't worth the trouble of building seperate functions for everything.

If you are still heavily mixing floats and doubles, you could also just template your functions.


By casting a constant double to a float is not going to slow me down at all! Casting a constant happens during compilation time if I am not mistaken. So when I write (float)1.28 it will be compiled as if I wrote 1.28f, right? (same with (double)1.28f and 1.28)
pinacolada
pinacolada
Here's the solution:

#pragma warning(disable: 4244)

:)
DigitalDelusion
DigitalDelusion
Quote:
Original post by pinacolada
Here's the solution:
#pragma warning(disable: 4244)


That's not a solution and if you were on my team (not that I even got a job so this is purly hypotetical) I would do my best to get your ass fired.

Warnings are a sign that something smells bad, always treat them with respect even if they're conversion warnings and then use good judgement to either rewrite, refactor or deem the appropriate conversion safe. In the long run it will save your ass more than it will ever hurt you to use good judgement.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
etothex
etothex
Quote:
Original post by iMalc

I'm with the original poster. I have done the same thing in the past.

There is a reason for this kind of thing. disk space usage for one. There are good reasons for not wanting to hard code everything to double right away. You may not want to be stuck using doubles at the end of your project, and may want the option of using floats instead to save disk space for example. He is not talking about being able to use both in the same compilation, but chosing which is used for the entire project.

As for float speed vs double speed. Perhaps you could post some real benchmarks that prove that accessing twice the memory (or even twice the hard disk amount) is actually going to be faster. Any time I've measured it the results said otherwise.

On the contrary to your paragraph 4. The memory savings could be extrmely high if you have a very large amount of floating point data and it can be reduced by a factor of two.

Templating functions is not in itself going to solve the warning he is getting. Explicit casting (as another poster mentioned) is still going to be required.

What is needed is for someone to post the exact string for turning off this specific compiler warning in the code. what is the #pragma disable number?


A 160GB hard disk costs $91US. That would be:

160*1000*1000*1000
160,000,000,000 bytes
9100 cents / 160,000,000,000 bytes
0.000000056875 cents / bytes
answer * 4 extra bytes for double vs. float

= 0.0000002275 cents in disk space you save each person by using floats instead of doubles. Woo hoo!

Memory you say? Hmm...

256MB DDR RAM costs $46

256*1024*1024
268435456
4600 / (256*1024*1024)
0.0000171363353729248046875
answer*4
0.00006854534149169921875 cents saved float over double

Just use the double. If you have a compiler for SSE/SSE2 then the speed difference is essentially 0, unless you're doing a whole lot of them (ie software 3D renderer)

*edit: to give you an idea how pointless it is to fret about it, gcc even has an option to make all floats double-precision.
CrazyMike
CrazyMike
If there are a significant amount of numbers being used for the float/double, the size difference can make a speed difference just because of cache hit/misses. Of course, what will happen with your code will depend on your circumstances.
Syntax without semantics is meaningless.
DigitalDelusion
DigitalDelusion
Memory issues are quite much more than a question about cents, transfer speed and as mentioned above cache issues are much bigger issues than mere memory consumption, and the junk about SSE2 making doubles as fast as SSE is utter rubbish since you can only work on half as many at one time because of their size.

If you're not doing scientific or numerical work and really need the extra precision that doubles gives stick to floats.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
pinacolada
pinacolada
Quote:
Original post by DigitalDelusion
Quote:
Original post by pinacolada
Here's the solution:
#pragma warning(disable: 4244)


That's not a solution and if you were on my team (not that I even got a job so this is purly hypotetical) I would do my best to get your ass fired.

Warnings are a sign that something smells bad, always treat them with respect even if they're conversion warnings and then use good judgement to either rewrite, refactor or deem the appropriate conversion safe. In the long run it will save your ass more than it will ever hurt you to use good judgement.


The compiler is not more intelligent than you. If you fully understand the problem that the warning is trying to tell you about, and you've decided that the performance loss is not an issue for your program (considering both the code you've written and the code you're going to write), then I see no problem with turning it off.

In general I agree that warnings should be respected. But this particular warning is pretty mild and I've turned it off in the past.
DigitalDelusion
DigitalDelusion
Quote:
Original post by pinacolada
The compiler is not more intelligent than you. If you fully understand the problem that the warning is trying to tell you about, and you've decided that the performance loss is not an issue for your program (considering both the code you've written and the code you're going to write), then I see no problem with turning it off.


No the compiler isn't smarter than me but it sees this kind of things that most of the time isn't a problem, but by keeping the warnings on and making a concious decision everytime they arise to either silience it by casting or reworking it if forces you to be aware of what you're doing. Also for multiperson projects turning a warning of can be a real annoyance as is not keeping your code warning free. I generally code with W4 (that would be the VC equvivalent of -Wall i guess) and tells the compiler to treat warnings as errors, it gives you good habits and when sharing code it also serves the purpose of not scaring anyone because they get a ton of warnings.

Quote:
Original post by pinacolada
But this particular warning is pretty mild and I've turned it off in the past.


That's your opinion and your'e entitled to it have it, I still strongly disagree.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.