unj*_*nj2 58 f# language-design
我从未见过语言有指数或幂运算符只采用浮点数?
例如:
2 ** 2 抛出错误 The type 'int' does not support any operators named 'Pow'
这个设计决定是否有正当理由?
Lau*_*ent 35
(**)并且pown是两件不同的事情.当你看到时(**),你可以用对数来思考数学公式.当你看到pown,它只是一系列的乘法.我知道它起初可能令人惊讶/困惑,因为大多数其他语言没有产生这样的差异(主要是因为整数通常被隐式转换为浮点值).即使在数学中,也存在一些小差异:参见维基百科条目,第一个定义仅适用于正整数指数.
由于它们是两种不同(但相关)的东西,它们具有不同的签名.这是(**):
^a -> ( ^b -> ^a) when ^a : (static member Pow : ^a * ^b -> ^a)
Run Code Online (Sandbox Code Playgroud)
这是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)
Run Code Online (Sandbox Code Playgroud)
如果你创建自己的类型,你只需要拥有你One,(*)和(/)得到它一起工作pown.库将为您完成循环(它已经过优化,它不是天真的O(n)).
如果要(**)在类型上使用运算符作为非整数值,则必须编写完整逻辑(并且它与算法不同pown).
我认为将这两个概念分开是一个很好的设计决策.
对于整数幂,F#提供另一个运算符:pown.此外,作为一个方面说明,两者(**)和pown过载,所以这是完全可能的与其它类型的,其提供适当的部件(一个静态使用它们Pow中的情况下,方法(**); (*)以及(/)运营商和静态One中的情况下,属性pown).
我不能说为什么F#团队选择不模拟Pow成员int,但也许他们觉得不紧急,因为pown可以使用运算符(并且因为它可能更有意义转换为浮点数在大操作数的情况).
简短的回答是因为它对于整数类型(甚至是 int64)来说并不是很有用。2^26 只能给你~1.84467441E19。因此,如果您有两个值 X 和 Y 都大于 19,那么幂运算符将导致溢出。
我同意它对于小值很有用,但是对于整数类型通常没有用。