为什么我不能比较标准ML中的实数? [英] Why can't I compare reals in Standard ML?

查看:171
本文介绍了为什么我不能比较标准ML中的实数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 为什么 1.0 = 2.0 不工作?是不是真正的一个相等类型?



    它给出了错误:

    错误:运算符和操作数不一致[所需的类型相同] 
    运算符域:''Z *''Z
    操作数:实数*实数
    在表达式中:
    1.0 = 2.0


  2. 像这样?

      fun fact 0.0 = 1.0 
    |事实上x = x * fact(x - 1.0)

    它给出错误:

     错误:语法错误:插入EQUALOP 



解决方案


为什么没有 1.0 = 2.0 工作?不是真正的是一个相等类型吗?


类型变量''Z 表示 = 的操作数必须具有相等类型。


为什么不能在模式中工作[...]?



<模式匹配依赖于测试的平等。隐含的错误消息语法错误:插入EQUALOP 表示SML / NJ解析器不允许浮点文字在预期模式的位置,因此程序员不能收到一个更有意义的类型错误。

详细说明,

来自 http://www.smlnj.org/doc/FAQ/faq.txt


Q:真的是平等型吗?



A:是SML90和SML / NJ 0.93,但不在SML '97和SML / NJ 110.
因此 1.0 = 1.0 将导致类型错误,因为=需要参数相等
类型。此外,真正的文字不能用于模式。


http://mlton.org/PolymorphicEquality


一种地面类型不能比较是真实的。所以, 13.0 = 14.0 是不正确的。可以使用 Real。== 来比较实数是否相等,但是要注意这有不同的代数性质,而不是多态性的等式。

http://sml-family.org/ Basis / real.html
$ b


确定real是否是一个相等类型,如果是这样,等于什么意思,也是有问题的。 IEEE指定在比较中忽略零的符号,如果其中一个参数是NaN,则等于false。

这些限制令SML程序员感到不安。前者意味着0 =〜0为真,而r / 0 = r /〜0为假。后者意味着r = r是错误的这种异常,或者说,对于一个参考单元rr,我们可以有rr = rr但是没有rr =!rr。我们接受了零的无符号比较,但是认为平等的反身性,结构性的平等以及<>和o =的等价性应该被保留下来。

简短版本:不要使用相等比较实数。执行一个 epsilon测试。我建议阅读 http://floating-point-gui.de/errors/comparison ,它总结了一大堆的陷阱。


  1. Why doesn't 1.0 = 2.0 work? Isn't real an equality type?

    It gives the error:

    Error: operator and operand don't agree [equality type required]
      operator domain: ''Z * ''Z
      operand:         real * real
      in expression:
        1.0 = 2.0
    

  2. Why won't reals in patterns work like so?

    fun fact 0.0 = 1.0
      | fact x = x * fact (x - 1.0)
    

    It gives the error:

    Error: syntax error: inserting  EQUALOP
    

解决方案

Why doesn't 1.0 = 2.0 work? Isn't real an equality type?

No. The type variable ''Z indicates that the operands of = must have equality types.

Why won't reals in patterns work [...]?

Pattern matching relies implicitly on testing for equality. The cryptic error message syntax error: inserting EQUALOP indicates that the SML/NJ parser does not allow for floating-point literals where a pattern is expected, and so the programmer is prevented from receiving a more meaningful type error.

To elaborate,

From http://www.smlnj.org/doc/FAQ/faq.txt:

Q: Is real an equality type?

A: It was in SML '90 and SML/NJ 0.93, but it is not in SML '97 and SML/NJ 110. So 1.0 = 1.0 will cause a type error because "=" demands arguments that have an equality type. Also, real literals cannot be used in patterns.

From http://mlton.org/PolymorphicEquality:

The one ground type that can not be compared is real. So, 13.0 = 14.0 is not type correct. One can use Real.== to compare reals for equality, but beware that this has different algebraic properties than polymorphic equality.

From http://sml-family.org/Basis/real.html:

Deciding if real should be an equality type, and if so, what should equality mean, was also problematic. IEEE specifies that the sign of zeros be ignored in comparisons, and that equality evaluate to false if either argument is NaN.

These constraints are disturbing to the SML programmer. The former implies that 0 = ~0 is true while r/0 = r/~0 is false. The latter implies such anomalies as r = r is false, or that, for a ref cell rr, we could have rr = rr but not have !rr = !rr. We accepted the unsigned comparison of zeros, but felt that the reflexive property of equality, structural equality, and the equivalence of <> and not o = ought to be preserved.

The short version: Don't compare reals using equality. Perform an epsilon test. I would recommend reading the article on http://floating-point-gui.de/errors/comparison which summarizes a bunch of pitfalls.

这篇关于为什么我不能比较标准ML中的实数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆