Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the power operator in F# only work for floating point numbers?

I have never seen a language have exponent or power operator only taking floating point numbers?

For example:

2 ** 2 throws an error The type 'int' does not support any operators named 'Pow'

Are there valid reasons for this design decision?

like image 411
unj2 Avatar asked Mar 17 '11 01:03

unj2


People also ask

How do you do powers in C?

pow() is function to get the power of a number, but we have to use #include<math. h> in c/c++ to use that pow() function. then two numbers are passed. Example – pow(4 , 2); Then we will get the result as 4^2, which is 16.

Does math POW return a float?

pow() function is that the math function will always convert both numbers to a float. Because of this, the result of the function will always be a float.

What is the exponent operator in Python?

The ** operator in Python is used to raise the number on the left to the power of the exponent of the right. That is, in the expression 5 ** 3 , 5 is being raised to the 3rd power. In mathematics, we often see this expression rendered as 5³, and what is really going on is 5 is being multiplied by itself 3 times.

How do you take the power of a float in Python?

The math. pow() method returns the value of x raised to power y. If x is negative and y is not an integer, it returns a ValueError. This method converts both arguments into a float.


2 Answers

(**) and pown are two different things. When you see (**), you can think of the mathematical formula using logarithms. When you see pown, it's just a series of multiplications. I understand it can be surprising/confusing at first, because most other languages don't make such a difference (mainly because integers are often implicitly converted to floating point values). Even in maths, there a small difference: See the Wikipedia entry, the first definition works only for positive integer exponents.

As they are two different (but related) things, they have different signatures. Here is (**):

^a -> ( ^b ->  ^a) when  ^a : (static member Pow :  ^a *  ^b ->  ^a) 

And here is pown:

^a -> (int ->  ^a) when  ^a : (static member get_One : ->  ^a) and       ^a : (static member ( * ) :  ^a *  ^a ->  ^a) and       ^a : (static member ( / ) :  ^a *  ^a ->  ^a) 

If you create your own type, you only need to have your One, (*), and (/) to get it work with pown. The library will do the loop for you (it's optimized, it's not the naive O(n)).

If you want to use the (**) operator on your type for non-integral values, you'll have to write the full logic (and it's not be the same algorithm as in pown).

I think it was a good design decision to separate the two concepts.

like image 192
Laurent Avatar answered Sep 19 '22 21:09

Laurent


For integral powers, F# provides another operator: pown. Also, as a side note, both (**) and pown are overloaded, so it's perfectly possible to use them with other types which provide appropriate members (a static Pow method in the case of (**); (*) and (/) operators and a static One property in the case of pown).

I can't speak to why the F# team opted not to simulate a Pow member on int, but perhaps they didn't feel it was urgent since the pown operator could be used instead (and since it probably makes more sense to convert to float first in the case of big operands).

like image 29
kvb Avatar answered Sep 19 '22 21:09

kvb