Haskell中与NaN的最大值和最小值

Haskell中与NaN的最大值和最小值,haskell,Haskell,为什么NaN和a的最大值是NaN,而NaN和a的最小值是数值?这似乎与我尝试过的其他几种语言不一致: 在哈斯克尔: max (0/0) 1 -- NaN min (0/0) 1 -- 1.0 用Python >>> max(float("nan"),1) #nan >>> min(float("nan"),1) #nan 在JavaScript中 > Math.max(0/0,1) //NaN > Math.min(0/0,1) //NaN

为什么NaN和a的最大值是NaN,而NaN和a的最小值是数值?这似乎与我尝试过的其他几种语言不一致:

在哈斯克尔:

max (0/0) 1 -- NaN
min (0/0) 1 -- 1.0
用Python

>>> max(float("nan"),1) #nan
>>> min(float("nan"),1) #nan
在JavaScript中

> Math.max(0/0,1) //NaN
> Math.min(0/0,1) //NaN
例如,
min1.0(0/0)
将返回NaN

这是因为与NaN的任何比较都被定义为返回false,并且通过以下最小值和最大值的定义:

max x y 
     | x <= y    =  y
     | otherwise =  x
min x y
     | x <= y    =  x
     | otherwise =  y
max x y

|x我不是Haskell程序员,但似乎浮点函数被称为
fmin
fmax
。无论出于何种原因,应用于浮点类型的泛型函数都不遵循标准的数值行为

fmin
fmax
符合IEEE 754:2008§5.3.1:

minNum(x,y)是标准化数x,如果x
请注意,此行为与JavaScript相反。不要像JavaScript那样做;v) .

哈斯克尔报告指定
(最小x y,最大x y)
将返回
(x,y)
(y,x)
。这是一个很好的属性,但很难与NaN的对称处理相协调


还值得一提的是,这与SSE2指令
MINSD
MAXSD
展示的不对称性完全相同,即Haskell
min
(对于
Double
)可以通过
MINSD
max
通过
MAXSD

实现,我不太确定,但我有一种感觉,这可能与
/
应用于
分数值而不是
积分值这一事实有关。如果您尝试使用
div
作为0
div
0进行除法,您会得到一个错误。@shree.pat18不是浮点吗?“在这种情况下,我认为它不适用于积分类型。@Davidyong是的,我同意。有趣的是,
1/0
返回
Infinity
,因此我不确定
0/0
会发生什么情况-它是否被视为Infinity,但显示为
NaN
,或者当它是参数之一时是否默认为
max/min
。可能会给出一些见解。从同一个线程,请参阅消息和。因此,这是
min
max
定义中的一个小错误(即,假设不是
)?IEEE 754:2008§5.3.1规定带NaN的
min
max
忽略NaN并返回数字。如果Haskell声称遵循标准的浮点行为,这是一个错误。标准中有没有提到>,这并不是为了回答这个问题-我不熟悉规范-我只是说,从数学角度来看,最小值和最大值的定义是正确的。当然,你不能订购NaN(如果你包括NaN,你会扔掉很多数学属性)-我只是想知道这些规格是否有点误导,或者甚至在某种意义上是自相矛盾的-所以永远不要mind@PotatoswatterHaskell并不声称符合IEEE 754。例如,在文章中,它说:“Haskell Prelude定义的默认浮点运算不符合当前的语言无关算术(LIA)标准。这些标准要求数字结构更加复杂,因此被归入一个库。IEEE浮点标准的某些方面(但不是全部)已在Prelude class
RealFloat
中说明
Ord
类需要将
min
max
作为符合此处IEEE754的方法。但由于IEEE754本身有点违背了对比较应该如何进行的更一般的理解,我认为Haskell没有这样做,只是提供了符合该标准的
fmin
fmax
。有人可能会说“预期”
NaN
行为不符合标准
Ord
规则:-)