2014-03-31 41 views
2

爲什麼指數運算符在OCaml中使用浮點變量? 它不應該允許int變量嗎?爲什麼指數運算符在OCaml中使用浮點變量?

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

作品:

# 3.0**3.0;; 
- : float = 27. 
+0

它不能讓'int'變量,即使它想,對於同樣的原因,在加法的情況下,爲int和float定義的操作,float類型的+。不允許使用int參數。這是一種權衡以便啓用類型推斷。對Hindley-Milner類型系統的擴展是必要的(並且已經設計了一些)以允許「5.0 + 5.0」和「5 + 5」。 OCaml的最短版本在實踐中是相當可接受的:在最近的版本中,你可以使用像'Float。(5.0 + 5.0)'這樣的東西。 –

+0

看看這個類似的問題:http://stackoverflow.com/questions/16950687/integer-exponentiation-in-ocaml –

回答

2

您可以使用int

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

我有點新Ocaml ...你能解釋這部分嗎? |> int_of_float 我不知道它爲什麼存在,或者它做了什麼。謝謝。 – SadSeven

+0

噢好吧,剛剛得到它......但它爲什麼會給錯誤? #let int_exp x y =(float_of_int x)**(float_of_int y)|> int_of_float ;; let int_exp x y =(float_of_int x)**(float_of_int y)|> int_of_float ;; 錯誤:未綁定值|> – SadSeven

+1

@SadSeven |>運算符包含在庫(如Core)中。自4.01版起,它也直接包含在該語言中。 –

2

所以,現有的答案進入如何解決這個問題,但不進它爲什麼是這樣。主要有兩個原因:

1)OCaml沒有運算符別名。你不能讓兩個操作符做「相同的事情」,但不同的類型。這意味着只有一種數字,整數或浮點數(或其他表示形式)才能使用標準**接口。

2)pow(),指數函數在歷史上已經定義在浮點數上(例如,Standard C)。

此外,爲了解決問題的另一種方法,如果您使用OCaml Batteries,則會爲整數定義一個pow函數。

0

有一個類似的問題:Integer exponentiation in OCaml

這裏是一個可能尾遞歸執行整數冪:

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