scheme - 用 OCaml 计算欧拉常数
问题描述
我今天开始学习 OCaml。我已经知道 Scheme,所以我认为尝试将一些示例 Scheme 程序转换为 ML 会很好。我在下面有一些代码用于计算欧拉数,它有效,但在 OCaml 中不起作用。我收到此错误:Exception: Division_by_zero.
我认为这可能是在某处混合浮点数和整数的问题。我一直无法弄清楚如何使用ocamldebug
. 谁能确定我的错误发生在哪里?谢谢你。
(define (factorial n)
(if (zero? n) 1 (* n (factorial (sub1 n)))))
(define (find-e accuracy sum)
(if (zero? accuracy) (add1 sum)
(find-e (sub1 accuracy) (+ sum (/ 1 (factorial accuracy))))))
(display (format "~f" (find-e 100 0)))
let rec factorial n = if n == 0 then 1 else n * factorial (n - 1) ;;
let rec find_e accuracy sum =
if accuracy == 0
then (sum + 1)
else find_e (accuracy - 1) (sum + (1 / factorial accuracy)) ;;
let result = find_e 100 0 ;;
解决方案
我记得,scheme 有一个“数字塔”,它试图防止你在数字计算中失去准确性。
OCaml 没有任何花哨的数字自动处理功能。您的代码使用 type int
,它是一个固定大小的整数(在通常的实现中为 31 或 63 位)。因此,在几乎所有情况下,您的表达式1 / factorial accuracy
都将为 0,并且factorial accuracy
除最小值之外的所有值都无法表示。的值factorial 100
将是0
因为它是 2^63 的倍数:
# let rec fact n = if n < 2 then 1 else n * fact (n - 1);;
val fact : int -> int = <fun>
# fact 100;;
- : int = 0
您的代码中没有浮点数,因此不可能有任何混合。但是 OCaml 一开始就不允许混合。它是一种强类型语言,其中int
和float
是两种不同的类型。
这是您的代码转换为使用浮点数:
let rec factorial n =
if n = 0.0 then 1.0 else n *. factorial (n -. 1.0)
let rec find_e accuracy sum =
if accuracy = 0.0 then
sum +. 1.0
else
find_e (accuracy -. 1.0) (sum +. 1.0 /. factorial accuracy)
let result = find_e 100.0 0.0
如果我将其复制/粘贴到 OCaml REPL(也称为“顶层”)中,我会看到:
val factorial : float -> float = <fun>
val find_e : float -> float -> float = <fun>
val result : float = 2.71828182845904509
作为旁注,OCaml 中的相等比较运算符是=
. 不要==
用于比较。这是一个完全不同的运算符:
# 1.0 == 1.0;;
- : bool = false
推荐阅读
- c++ - 使用 c++11 基于范围的循环搜索插入位置
- node.js - razorpay支付测试模式下点击“失败”如何调用API?
- r - 从R中的列表制作一个JSON
- python - 如何在 Python 中使用 MLE 估计高斯分布参数
- matplotlib - 刻度标签与自定义脊椎重叠轴;制作“数学”图
- xml - 使用 Groovy 在日志文件中定义多个 XML 行
- javascript - 我该如何解决这个错误?错误:找不到模块
- java - JavaFX 矩形监听器
- angular - Angular 4 不发送一些请求
- vue.js - 使用从获取的数据中计算出来的计算数据的正确方法是什么?