Raising to powers in C++ vs. Python

2019-04-30 14:25发布

问题:

Coming from Python, I've noticed things in C++ tend to be a little more complicated. A good example would be raising numbers to a power. In Python's math library, all that is needed is:

a = a**b

However, in C++ I've found explanations in online documentation such as.....

//float
pow( float base, float exp );
//double      
pow( double base, double exp );
//long double 
pow( long double base, long double exp );
//float
pow( float base, int iexp );
//double      
pow( double base, int iexp );
//long double 
pow( long double base, int iexp );
//promoted    
pow( Arithmetic1 base, Arithmetic2 exp );

Obviously the creators of C++ must have had great reasons for making it this way, but as a new programmer, those reasons elude me. Does this give greater flexibility over the answer? What benefits have I been given here in C++ in terms of powers?

回答1:

Numbers in python have no limit. Some consequences that arise out of this is that programs tend to be slower since python is not statically typed, and has more overhead since it does not know if a number is within a certain range. In short, the main reason for using overloading functions in that way is for speed purposes, and it's easier to reason about what's happening under the hood. Python provides a lot of conveniences, but sometimes become very difficult to reason about.

Secondly, most languages have a math.pow function (Java also for example), and while it's a bit verbose, I think it's still very easy to understand. Note that when you call pow() in C++, the compiler will figure out which of the pow(some data type, some data type) should be called and there is no need to worry over the multiple definitions.



回答2:

The multiple declarations you found are a result of C++ having static types vs. Python's dynamic types. In Python when you call a function on a value it can determine at runtime if you are calling it on an integer, float, or some more complex object and take the appropriate actions. In C++ you can't call the same function with different types so you must declare a different version of the function for all the types you wish to support. However unlike in C, you can have functions with the same name that differ only in their parameter signature, (as Untitled123 points out, this is called function overloading). This actually makes your life easier since you can just call pow(a,b) without having to worry about which special function to call for the types you want (e.g. pow_float_int(a,b) or pow_float_float(a,b)), the compiler will call the correct version for you based upon the types of the arguments.



回答3:

The benefits of having multiple function signatures is in compile-time optimization vs. run-time decision.

In Python, ** operation looks at its arguments at run time and decides what algorithm to apply. The integer exponent vs. rational exponent vs. arbitrary floating point unlimited precision exponent vs. complex exponent vs. whatever else. This decision takes time.

In C++, as compiler sees pow(x, y), it knows the types of x and y at the compilation time, so it can pick the best matching pow(). That, in turn, allows the compiler to avoid any kind of runtime decision making. Depending on how headers are written and/or the presence of whole program optimization, the compiler can even inline the call and avoid any kind of runtime expense apart from actually computing the power.

This usually does not matter much. However, if your pow() call is in a tight loop with millions of iterations, it can be significant.



回答4:

as you know in c++ we use function for Power instead of operators ( like python )

you can use pow as like as above examples. There are several modes for use of this function and every time you send different variables to it, system decides which mode to choose . pow( float base, float exp ); and pow( double base, double exp ); are not the same and each are a separate function

Now when you go to the Python there are exactly same state . ** Operator is like the C++ functions that have different modes . Just like the definition of the operators in C++

I hope you understand my tip