Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Function returning double parameter

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
Function returning double parameter
Evert
Member #794
November 2000
avatar

Quote:

Did you read the rest of the post?

Of course I did. >:(::)::)::)::)>:(

Did you get my point?

gnolam
Member #2,030
March 2002
avatar

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?"

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Evert
Member #794
November 2000
avatar

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
avatar

22/7 = 3.1428571428571428571428571428571
pi = 3.1415926535897932384626433832795
22/7 - pi = 0.00126448926734961868021375957764
pi - 3.14 = 0.0015926535897932384626433832795029

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 ancient egiptyans used 19/6 for pi, which is worst than 22/7.

[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
avatar

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 ;D )

----
Oh... Bieber! I thought everyone was chanting Beaver... Now it doesn't make any sense at all. :-/

Evert
Member #794
November 2000
avatar

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
avatar

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
avatar

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
avatar

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).
As I said above,

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.
Anyway, if you're optimising that, you're probably optimising the wrong thing.

X-G
Member #856
December 2000
avatar

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?

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Ron Ofir
Member #2,357
May 2002
avatar

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
avatar

There's a pretty good chance 22/7 will be calculated at compile time, yes. Constant expressions are a pretty trivial optimization.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Arthur Kalliokoski
Second in Command
February 2005
avatar

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
avatar

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 >:( ) I recall that modern processors need 1 clock cycle for one multiplication. Regardless of the numbers being float or double. Have to find the reference article though...

FMC
Member #4,431
March 2004
avatar

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?
For example (as i wrote before), imagine i have a complicated function
(float f(float x);), if i knew only 3 digits of precisions are needed, i could simply multiply the entering value by 1000 and storing it in an int do all calculation using integers (faster), divide by an integer 3142, continue my calculations and only at the end divide by 1000.0 - if the function is complex enough you gain much more by using ints than what you loose for the 2 extra operations...
but really it's not really something important as either way it doesn't really matter.

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]
Written laws are like spiders' webs, and will, like them, only entangle and hold the poor and weak, while the rich and powerful will easily break through them. -Anacharsis
Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails. Explore. Dream. Discover. -Mark Twain

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. :D Hehe, but that was of course just for fun. Using a well defined constant is the nicest approach.

Fladimir da Gorf
Member #1,565
October 2001
avatar

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
avatar

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.
That said, cumulative errors from intermediate rounding reallydo matter, and you should not round until the last step if you can possibly avoid it. I've once had a discussion about that when I was in highschool with my chemistry teacher, who maintained that it's ok. Which was why his answers were always a bit off in the last few digits "due to rounding errors".

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
avatar

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
avatar

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
avatar

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.
Personally I always use doubles for the extra precision.

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
avatar

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
avatar

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)

 1   2   3 


Go to: