为什么指数运算符在 OCaml 中使用浮点变量?

 2022-01-08 

Why does the exponential operator use float variables in OCaml?

为什么指数运算符在 OCaml 中使用浮点变量?
它不应该也允许 int 变量吗?

1
2
3
# 3**3;;
Error: This expression has type int but an expression was expected of type
         float

作品:

1
2
# 3.0**3.0;;
- : float = 27.


因此,现有的答案涉及如何解决这个问题,但没有涉及为什么会这样。主要有两个原因:

1) OCaml 没有操作符别名。你不能有两个操作符做"同样的事情",但是不同的类型。这意味着只有一种数字、整数或浮点数(或其他一些表示)可以使用标准 ** 接口。

2) pow(),幂函数历来是在浮点数上定义的(例如,在标准 C 中)。

此外,对于解决该问题的另一种方法,如果您使用包含 OCaml 电池,则有一个为整数定义的 pow 函数。


你可以使用 int

1
let int_exp x y = (float_of_int x) ** (float_of_int y) |> int_of_float


有一个类似的问题:OCaml 中的整数取幂

这是整数取幂的一种可能的尾递归实现:

1
2
3
4
5
6
7
8
9
10
11
12
let is_even n =
  n mod 2 = 0

(* https://en.wikipedia.org/wiki/Exponentiation_by_squaring *)
let pow base exponent =
  if exponent < 0 then invalid_arg"exponent can not be negative" else
  let rec aux accumulator base = function
    | 0 -> accumulator
    | 1 -> base * accumulator
    | e when is_even e -> aux accumulator (base * base) (e / 2)
    | e -> aux (base * accumulator) (base * base) ((e - 1) / 2) in
  aux 1 base exponent