|
|
| Function returning double parameter |
|
Evert
Member #794
November 2000
|
Quote: Did you read the rest of the post?
Of course I did. Did you get my point? |
|
gnolam
Member #2,030
March 2002
|
Quote: Did you read the rest of the post? I did. And you still haven't provided an answer to what we're asking, namely: "When you can do something right for no more cost or effort than doing it wrong - why the hell should you choose to do it the wrong way?" -- |
|
Evert
Member #794
November 2000
|
I'll restate what I was trying to point out in a more direct way: to no number of significant digits is it better to use 22/7 instead of the value of pi to said number of digits. The best case is 1 significant digit, for which case the difference is zero (since both are 3 in that case). The best case is for three digits, where pi is 3.14 and 22/7 is 3.15. It gets worse from there. |
|
Victor Williams Stafusa da Silva
Member #4,212
January 2004
|
22/7 = 3.1428571428571428571428571428571 22/7 is a better aproximation to pi than 3.14. I frequently saw 3.14 being used as a aproximation to pi in several games without any noticeable glitch caused by that. So 22/7 should be ok for many practical purposes too. However, something that should be noted is that 22/7 > pi and 3.14 < pi, this could make a difference in some cases. [offtopic Edit:] [The attack of the space bugs - Speedhack 2005] [Rambananas - Speedhack 2006] [Make clean - Speedhack 2009] [The source god - TINS 2010] |
|
Ron Novy
Member #6,982
March 2006
|
The small inacuraces would hardly be noticable but I believe it is just better practice, from a programming perspective, to use M_PI or AL_PI (or just memorize 3.141592653589793238462643383279502..... Then you could create a multi-player game where the winner is the one who has more of PI memorized ---- |
|
Evert
Member #794
November 2000
|
Quote: The small inacuraces would hardly be noticable It can be very noticable. The example I gave for firing missiles across the screen was from experience: a missile fired from the left of the screen towards a stationary target on the right of the screen under an angle would miss because I was trying to be clever and calculate with lower accuracy. But yes, the point was that if youcan do it right, why wouldn't you? |
|
Arthur Kalliokoski
Second in Command
February 2005
|
If accuracy doesn't count, you might gain a bit of speed by using floats rather than doubles. They all watch too much MSNBC... they get ideas. |
|
TeamTerradactyl
Member #7,733
September 2006
|
Hey, if everyone else is jumping into this... I would think that defining your own PI variable would be more efficient than calling "22/7" each time the function is called. Just less math that the computer has to compute in the routine. That way, you have a 3- 5- or n- precision number to your liking that's been calculated ONCE and you don't need to run the math through every time. I would think that M_PI, PI, AL_PI, or simply float MY_PI = 3.1415 would increase the speed of the function. #define MY_PI 3.14159 double grad2rad( int grad_angle ){ return (double)(MY_PI * ((double) grad_angle))/180.0; } Just my 2 cents...
|
|
Evert
Member #794
November 2000
|
It isn't wrong to use floats instead of doubles, it's wrong to use a poor approximation to pi if you can use pi proper (to a given number of digits). Quote: to no number of significant digits is it better to use 22/7 instead of the value of pi to said number of digits EDIT Quote: "22/7" each time the function is called. Just less math that the computer has to compute in the routine.
22/7 is a compile time constant, so it's evaluated at compile time (as opposed to runtime) by any decent compiler. |
|
X-G
Member #856
December 2000
|
You're still dodging the core issue. Typing M_PI instead of 22/7 would give you superior accuracy at no cost whatsoever. How can one even possibly defend doing this wrong? -- |
|
Ron Ofir
Member #2,357
May 2002
|
Quote: Just less math that the computer has to compute in the routine. That is wrong. AFAIK, the compiler calculates as many constant values as it can during compile-time (I think I've read that in an old K&R book, so it must be even better now) so it really doesn't matter. BTW, using that, you can still leave some constant expressions in your program to make it more readable, knowing that the compiler will take care of it. |
|
X-G
Member #856
December 2000
|
There's a pretty good chance 22/7 will be calculated at compile time, yes. Constant expressions are a pretty trivial optimization. -- |
|
Arthur Kalliokoski
Second in Command
February 2005
|
Quote: I would think that defining your own PI variable would be more efficient I have seen where using a global variable is faster than a constant, as always, if it's not in a bottleneck, don't worry about it, else time it and see. It'd help if it was near to another recently used global if any. const float mathpi = M_PI; Last time I looked at the asm output for a defined double it had to allocate and write two separate 32 bit values to the stack. They all watch too much MSNBC... they get ideas. |
|
tobing
Member #5,213
November 2004
|
Do some profiling, or write a simple benchmark program. Is float really faster than double? On modern processors, I strongly doubt that... A float is a float is a float, whatever number of digit you try to put into it (after the , of course). Division needs several cycles, so a measure would be needed. From my memory (can't find the article I've read about this some time ago |
|
FMC
Member #4,431
March 2004
|
Quote: You're still dodging the core issue. Typing M_PI instead of 22/7 would give you superior accuracy at no cost whatsoever. How can one even possibly defend doing this wrong? Except I never said to use 22/7 instead Quote: I did. And you still haven't provided an answer to what we're asking, namely: "When you can do something right for no more cost or effort than doing it wrong - why the hell should you choose to do it the wrong way?" Because there are "wrong" ways that do the job at a lower cost? Quote: With some types of games it does. Suppose you have a racing simulation where you simulate the suspension and all other things. Now if after a few seconds the suspension starts to wobble more and more and finally goes completely out of control because you're physics simulation is unstable, then I'd say it matters. I'd say a simulation is extensively based in physics, so it does make sense to use a good, even if complicated, model. That said i don't see how it hurts to use a rounded value if you are just using it for some particicle effects... [FMC Studios] - [Caries Field] - [Ctris] - [Pman] - [Chess for allegroites] |
|
kentl
Member #2,905
November 2002
|
I made a little (ugly [I'm still a beginner at it]) Haskell program: fractions = [(x,y) | x <-[1.0, 2.0..250.0] , y <-[1.0, 2.0..250.0] ] difference f = map (\(x,y) -> abs (pi - x/y)) f fracwithdiff = zip fractions (difference fractions) approx [] ((a,b),c) = ((a,b),c) approx (((x,y),z):xs) ((a,b),c) = if z < c then approx xs ((x,y),z) else approx xs ((a,b),c) When I run it: Main> approx fracwithdiff ((1,1),1) ((245.0,78.0),0.000567012564152147) Main>
So instead of writing 22.0/7.0 you could write 245.0/78.0 and get even better precision. |
|
Fladimir da Gorf
Member #1,565
October 2001
|
Quote: storing it in an int do all calculation using integers (faster) It's not, floating point math isn't slow these days. With all those divisions (which may take dozens, if not hundreds of cycles) anyways. And floats aren't more processor efficient, they're only more memory efficient. Both floats and doubles are expanded to 96 bits before any calculations. OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
|
Evert
Member #794
November 2000
|
Quote: Is float really faster than double? On modern processors, I strongly doubt that... You're wrong then. Especially if you're doing a lot of floating point calculations you can really notice the difference. I suspect it is mainly a bandwith issue, however. Quote: A float is a float is a float, whatever number of digit you try to put into it (after the , of course). Yes, except if the number of bytes in which it is stored is different (obviously). Quote: Because there are "wrong" ways that do the job at a lower cost? Re-read gnolam's post (or my earlier post). Especially the bit that says When you can do something right for no more cost or effort than doing it wrong. Quote: if i knew only 3 digits of precisions are needed
If you're only going to need three significant digits, then you may want to have pi to only three significant digits as well. That's not doing it wrong, that's doing it with limited precision. What's wrong is using a value of pi that is accurate to three digits while the rest of your numbers are accurate to sixteen (say) digits. Which is what I've said two times already. Quote: if the function is complex enough you gain much more by using ints than what you loose for the 2 extra operations... Did you benchmark that or did you pull that from thin air? float<--->int conversions are slow in themselves. |
|
tobing
Member #5,213
November 2004
|
Quote: doing a lot of floating point calculations you can really notice the difference. I suspect it is mainly a bandwith issue, however. I definitely have to find that article again. Also I'm used to consider 64 bit processors (all brands), and there the difference between float and double computations is not noticable. In fact, as Fladimir Quote: Both floats and doubles are expanded to 96 bits before any calculations indicates, floats are expanded to the full length of the corresponding registers anyway. But as long as I don't find the already mentioned reference, most of this in only guessing... |
|
kentl
Member #2,905
November 2002
|
Quote: full length of the corresponding registers anyway I thought the registers in a 64-bit processor was of length 64-bit. And that's how you classify a 64-bit processor. Are you saying that todays 64-bit processors in fact have registers holding 96-bit? |
|
tobing
Member #5,213
November 2004
|
I've asked one of our specialists: In a 64 bit processor, the double registers hold 128 bits. The integer width is 64 bits. The number 64 mostly indicates the width of the data bus, so there's no reason why a 32 bit processor can't have 64 bit registers (as are the double registers in a P4 processor), but could have even more. I don't know about the MME or SSE registers, I'll try to find some references today. How many bits does AGP have? And PCIe? I thought it was 128 bits, so you could push 4 integers from CPU to the GPU in 1 cycle! |
|
Evert
Member #794
November 2000
|
Quote: I definitely have to find that article again. Also I'm used to consider 64 bit processors (all brands), and there the difference between float and double computations is not noticable.
My collaborator doing hydrodynamical simulations of colliding stars says otherwise from experience, and I sooner believe him. As I said, I suspect it's a bandwidth issue. |
|
kentl
Member #2,905
November 2002
|
Quote: In a 64 bit processor, the double registers hold 128 bits. To my understanding a double register is just two normal registers which you can use for a limited number of things. If there are assembler directives which can handle double register arithmetic then those directives takes twice as long to execute as the ones which uses normal registers. Is that wrong? In my book on Microprocessors it says that it's mostly the register width which is used to classify a processor as X-bit. Quote: I've asked one of our specialists I rather read what someone here who knows this stuff has to say. I've only taken one Microprocessor course as I study CS. But there are lots of people here with good knowledge of hardware. Let's hope they pop up. |
|
tobing
Member #5,213
November 2004
|
I'm reading through the "Intel 64 and IA-32 Architectures Software Developer's Manual", downloaded from www.intel.com. The table on page 53 gives a lot of numbers: For all Pentium processors, the external data bus has 64 bits. The general purpose registers all have 32 bits. The floating point registers have 80 bits. Then there are MMX registers, which all have 64 bits, and XMM registers, used for SSE2 and later, which all have 128 bits. Internal data paths are 2-4 times wider than the external data bus. This paper does only describe HOW the assembler statements work, not how many cycles they use. Next paper... "IA-32 Intel Architecture Optimization Reference Manual" gives a lot of hints how to improve speed when dealing with anything. However, it seems that all this stuff is pretty complicated, and again, no numbers of clock cycles are given. One thing I now have learned from this is: Most probably, it's entirely unimportant how many cycles the multiplication (or any operation) exactly has. There are other limiting factors, which mostly concern the ability of the processor to do things in parallel (blocking events), and when to get or store data. Cache is important here, branch prediction, and more... So I would only go for correctness, then do profiling if things are too slow. |
|
Fladimir da Gorf
Member #1,565
October 2001
|
The MMX registers are often the same as the floating point registers (at least, they used to be). That's why if you're doing MMX calculations, you can't do any floating-point calculations before you've called EMMS. But yeah, I remembered wrong. The size of the FP register is 80 bits. But the same registers are used with both floats and doubles, so there's no difference in calculation speed. OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
|
|
|