首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解函数中的数字数据类型

理解函数中的数字数据类型
EN

Stack Overflow用户
提问于 2014-01-25 22:04:38
回答 1查看 82关注 0票数 2

这是我之前发布的关于双浮的问题的后续内容。我为可能是Lisp的基本概念道歉,但我还没有领会它。

对于这个问题,我使用的是GNU CLISP 2.49 (2010-07-07)

假设我有以下函数,它简单地通过牛顿法确定平方根:

代码语言:javascript
复制
(defun sr (n eps)
  (when (>= n 0)
    (do ((x (/ n 2.0) (/ (+ x (/ n x)) 2.0)))
      ((< (abs (- (* x x) n)) eps)
       x))))

我可以这样称呼它:

代码语言:javascript
复制
> (sr 2 0.00001)
1.4142157

它给了我单精度浮动(缺省值)。合乎道理。由于缺乏精确性,如果eps太小,它就不能正常工作,进入无限循环:

代码语言:javascript
复制
> (sr 2 0.00000001)
[just sits there...]

如果我用双精度值调用它,仍然会得到单精度结果:

代码语言:javascript
复制
> (sr 2.0d0 0.00001d0)
1.4142157
> (sr 2.0d0 0.00000001d0)
[just sits there...]

但是,如果我将我的功能重新定义如下:

代码语言:javascript
复制
(defun sr (n eps)
  (when (>= n 0)
    (do ((x (/ n 2.0d0) (/ (+ x (/ n x)) 2.0d0)))
      ((< (abs (- (* x x) n)) eps)
       x))))

不管我怎么喂它,我都能得到双倍的精度:

代码语言:javascript
复制
> (sr 2 0.00001)
1.4142156862745097d0

现在,由于精度的提高,一个更小的eps可以工作:

代码语言:javascript
复制
> (sr 2 0.00000001)
1.4142135623746899d0

因此,我的问题是:函数应用的精度是否完全取决于它在其包含的算术表达式中所使用的常量中指定的精度?如果是的话,如果函数中没有常量呢?那么是什么决定了计算和结果的精度呢?

增编

我刚刚在SBCL 1.0.57-1.fc17上重新测试了这一点,根据@JoshuaTaylor在评论中引用的文档,我得到了更多预期的结果。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-25 22:12:13

在我看来,这是CLISP与ANSI CL标准的不兼容。

ANSI CL标准要求结果是所有参数中最大的类型:

代码语言:javascript
复制
CL-USER 20 > (/ 2.0d0 2.0)
1.0D0

CLISP给出:

代码语言:javascript
复制
[4]> (/ 2.0d0 2.0)
1.0

这应该是双浮子。

您可以在CLISP中将其更改为标准的ANSI CL行为

代码语言:javascript
复制
[9]> CUSTOM:*FLOATING-POINT-CONTAGION-ANSI*
NIL
[10]> (setf CUSTOM:*FLOATING-POINT-CONTAGION-ANSI* t)
T
[11]> (sr 2.0d0 0.00001d0)
1.4142156862745097d0

现在,它返回所需的结果。

参见CLISP手册:12.2.4.1.浮子精密接触规则

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21356845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档