And don't forget heavenly expressions like pow(x, pow(pow(x, pow(x,0)),0))
Kapow!
This is a discussion on Function within the C++ Programming forums, part of the General Programming Boards category; And don't forget heavenly expressions like pow(x, pow(pow(x, pow(x,0)),0)) Kapow!...
And don't forget heavenly expressions like pow(x, pow(pow(x, pow(x,0)),0))
Kapow!
In these days of gigahertz and gigabytes, readability comes before small optimizations like these.
Would you write x * x instead of using the proper notation if you were writing this on a piece of paper? I would say that readable code should strive to follow the same mathematical notation as is used everywhere else, whenever possible. So if i want to multiply a variable with another one, i would use the * operator, and if i wanted to raise x to some power, i would use pow(), since we obviously cannot use the ^operator.
Just because these two operators can be mixed without changing the result, does not mean it produces more readable or understandable code, on the contrary, it's a trick to avoid using some specific function, sounds a bit like premature optimization to me
Ofcourse, if the cmath library hadn't been includde for other purposes in the OP, there would be no point at all in using pow() for such a trivial expression, i just don't see a reason to avoid using the correct function pow() for squaring, when it is readily available in the program already.
How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.
I posit that the function call does not increase readability.Originally Posted by Neo1
Probably not. I would use superscript notation. I would certainly not write pow(x, 2).Originally Posted by Neo1
Unfortunately, it is impossible in C++, and you have noted yourself. I might write x ** 2 in Python, but even then x * x looks simpler to me.Originally Posted by Neo1
That said, there are other considerations, e.g., if x were a more complicated expression instead, then pow(x, 2) (or x ** 2) may well be a simplification (and we avoid evaluating the expression twice).
In other words, pow does not make the code more readable since the expression is so trivial that it is trivially understood either way, hence defeating the core of your argument.Originally Posted by Neo1
Choosing the more efficient of two readable options is not premature optimisation. It is common sense.Originally Posted by Neo1
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
The fact that pow() is less efficient is only one of MANY reasons it is inappropriate. Squaring a number is, by definition, multiplying it with itself. Writing it as pow(x, 2.0) is a "premature generalization." It also implies that you don't understand what squaring means.
If I were writing it on paper I would use a superscript. I wouldn't write pow(x,2.0).Would you write x * x instead of using the proper notation if you were writing this on a piece of paper?
So if you COULD use '^' that would somehow be more intuitive or obvious? Explain. What does '^' have to do with exponentiation?if i wanted to raise x to some power, i would use pow(), since we obviously cannot use the ^operator.
Anybody who actually needs to square numbers as part of real code they are working on will have no problem understanding what is happening, nor will anybody else who reads or works with that code. You're inventing imaginary problems.Just because these two operators can be mixed without changing the result, does not mean it produces more readable or understandable code, on the contrary, it's a trick to avoid using some specific function, sounds a bit like premature optimization to me
Here's a mind-blower for you -- what's the best way to take a square root? sqrt(x) or pow(x, 0.5)?
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}
Neo, you're beating a dead horse. It seems to me that you've reached the point where you're just disagreeing for the sake of disagreeing.
It comes down to these things:
A mathematical equation in C++ in general isn't going to look like the written form. Trying to make it look exactly so leads to nothing but disappointment and obfuscation. It's a failure to understand the meaning of the equation and translate that to an appropriate algorithm. If you want to exactly represent a written mathematical equation then you're using the wrong tool for the job.
Using what is asbolutely well known to be identical except faster and ususally shorter to write out, is not premature optimisation. Using the slower, longer, and more complex to type out one intentionally, is just outright stupid.
It is quite common for the simpler, more specific operation to be more efficient and overall tidier than the general one. pow is more general because you can raise to any power you like such as 2.1. Straight multiplication between two variables is simpler and specific to the power undeniably being 2.0. sqrt(x) is another case. The sheer fact that sqrt can't raise a value to the power of 0.4 or any other value for example means that the assembly code or circuitry required to perform the operation is going to be able to take advantage of more assumptions and thus be simpler. It's that lack of generality that gives it the edge.
It's just like how a swiss army knife does a mediocre job at a lot of things. If you want to do one thing and have it done well, then there is a better more specific tool out there for the job. In this case, multiplication is that tool.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
Although I disagree with Neo1, I can explain that one.
Most mathematicians will be familiar with the notion of using ^ for superscripting, and x^2 will be understood as "x squared". That convention is supported by most variants of TeX and also by maple, which are two most commonly used packages, particularly by mathematicians, for typesetting mathematics. TeX packages, for example, are freely available and most mainstream mathematical journals will accept submissions in the form of TeX files because it can produce photo-ready output directly for publication.
However, arguing that one should use pow() because we can't use ^ for exponentiation, is the height of silliness. pow() is not a mathematical notation.
Neo1's argument that source code should express concepts in the same way a mathematician would is specious and academic, and doesn't work in the real world. The whole point of mathematical derivations is to express a concept (or an algorithm) in a form that allows it to be understood and (to anyone except possibly a pure mathematician) to be applied. Any mathematician worth their salt expects that someone who is attempting to use their work (formulae, etc) will interpret in a context that makes sense to the application. They expect that a software engineer will take steps to ensure the code works correctly, is numerically stable, is maintainable, etc etc. They do not expect that a software engineer will slavishly follow mathematical notations at the expense of remotely sane programming practice.
If you want an example of that, consider Gaussian elimination and the Gauss-Jordan elimination. Technically, they are both techniques for solving a system of linear equations with a square coefficient matrix. They are mathematically equivalent (the only difference is that Gaussian elimination reduces the coefficient matrix to upper triangular form, and Gauss-Jordan elimination performs operations in a different order and reduces the coefficient matrix to the identity matrix). To a mathematician, the two algorithms are equivalent. However, when used to solve a system of linear equations on a computer, Gaussian elimination is generally both faster and has better properties related to numerical stability. However, on paper, the solution of a linear equation A*x = b is often expressed by mathematicians as x = A(inverse)b (or $x=A^{-1}b$ in TeX notation) and Gauss-Jordan elimination can be used to directly produce A(inverse). By Neo1's argument, the best algorithm to use for such an expression is Gauss-Jordan elimination.
Edit: Oh, and x = pow(A, -1)*b will not work either.
Thankfully, mathematicians and computer engineers are often both more pragmatic than that.
Last edited by grumpy; 09-27-2011 at 01:45 PM. Reason: Fixed minor typos
Besides the obvious (from my point of view) choice between x*x and pow() I would also like to point that the gravitational constant could also be written as: 6.673 * 0.00000001 to allow those compilers without intrinsic functions to make some optimizations. It is not that hard to write a couple of important physics constants this way and the advantage may be big, since this will allow the compilers to evaluate the expression at compile-time.
I never put signature, but I decided to make an exception.
I concede, perhaps talking about readability in regards to such trivial expressions don't make sense. I will just say this however, Brewbuck, you strike me as a particularly angry individual. This thread consisted mostly of friendly banter until you came along, guns blazing, commenting repeatedly about my lack of mathematical prowess, you know full well that i have a firm grasp of what squaring a value means. I'm here to get smarter, it seems you are here to squash whoever is not in agreement with you.
How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.
It's been a while since you posted this, but I only just saw it now and you deserve a response from me.
My quip about your knowledge came across a lot worse sounding than I intended, and I will try to be more careful about how I phrase things in the future.
I tend to be rather crushing in my criticisms when I know for sure that something is wrong with an argument, implementation or otherwise. This is sort of inherited from all the people I've worked with over a long period of time. Respect people, respect effort, respect curiosity, respect experimentation, but have a very low tolerance for things which simply aren't correct. It becomes heated when one person's idea of "correct" does not match with someone else's. Anger is hard to judge across the Internet. Do I believe that I'm right and you aren't? Certainly, and I do not apologize for that, but I was not angry and I regret that it seemed that way.
Also, I have a bad habit of using "you" as a stand-in for "a generic person" and I sometimes switch between addressing a specific person and talking generally, which can be confusing at best, and although I don't remember for sure what I was thinking when I wrote my post, I'm pretty sure I didn't mean to call you an idiot, because I don't think you are one.
My apologies.
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}