【问题标题】:Why are NaN floats? [closed]为什么 NaN 是浮点数? [关闭]
【发布时间】:2023-01-31 20:24:39
【问题描述】:

除以零会导致对象出现,这些对象虽然被键入为数字,但不是有效数字。这导致为数字数据类型创建 NaNs values,主要用于浮点运算(因此在大多数编程中使用 float 类型)。

由于在操作整数时也可能发生被零除,为什么不存在“NaN 整数”?

我正在寻找有关解释此模式的编程约束的记录答案。

【问题讨论】:

  • PEP 是 python 标准,而不是 numpy 或 tensorflow。如果您正在寻找“为什么”,那不是 Stack Overflow 的主题,但 this NEP on missing data 可能就是您要找的。 numpy 从 IEEE 数据类型标准中获取其类型定义 - 请参阅 numpy miscelaneous docs on floating point special valuesIEEE_754
  • 我知道 PEP 是 Python 标准。我正在寻找语言或编程约束历史的解释,证明没有其他语言中存在的整数 NaN。
  • 是的,如果你准备使用 pandas dtypes,pandas 引入了一个可为空的整数类型(类型 Intint 不同),记录在这里:pandas.pydata.org/docs/user_guide/integer_na.html
  • 等等,你是说整数 nans 在其他语言中是正常的?这些是什么语言?!
  • 如果您使用的是 Python,则可以查看 masked arrays 以了解在整数数组中包含缺失值的方法

标签: floating-point integer nan


【解决方案1】:

因为所有的整数都是一致的,都有一个值。

一个 8 位无符号整数从 0000000011111111,所有这些值都有一个明确定义的值,即从 0 到 255。

您会牺牲其中的哪一个值来编写 8 位无符号整数 NaN? 255也许吧。但是,你牺牲了很多可能的应用程序。您不能使用 8 位无符号整数来处理字节(因为它们在 [0,256) 中)。也不使用它们来处理图像(白色 (255,255,255) 像素将是 (NaN, NaN, NaN))。等等。

如果11111111 unsigned 8bits int 表示 NaN,则甚至没有提到所有变得不可能的优化,但是 11111111 signed bits int 表示 -1(它必须这样做)

当然,您可以改用 16 位整数。但这将需要所有这些应用程序的两倍内存(而这些应用程序恰好是有时甚至 64Gb 内存不足的应用程序使用。我目前正在开发这样的应用程序,其中我的缓冲区图像使用所有我的 64 Gb。将我的缓冲区容量减半会花费很多,只是因为我可能需要对整数 NaN 进行编码的可能性很小)。

因为,这是它不是这样的另一个原因:为什么有人需要它?我的意思是,NaN 的意思是“不是数字”。这意味着存储在内存位置的位实际上并不代表数字。

花车是不同的。因为浮点数的经典 IEEE 编码使某些位组合变得无意义(或特殊)。不多。它不像是 1 个未使用的位,或任何类似的东西。数十亿可能的值中只有少数不可能的值。但是,某些位的组合仍然无效。或者,更准确地说,我们赋予了它们一些特殊的含义,包括 NaN。

对于 int,由您决定,对于您的应用程序,您可以牺牲一个值。例如,如果您要存储骰子输出,您有足够多的选择来决定一个值(-1、0、7、99,...除 1、2、3、4、5 或 6 之外的任何值)将具有对你有特殊意义(例如“骰子没有掷”)。系统不能承担牺牲某些位组合的责任,即一些可能的值,以使其具有特殊性,即使对于那些不需要任何此类特殊值的人也是如此。

对于浮点数,好吧,因为已经有一些不可能/冗余的位组合,所以给它们特殊的名称不需要任何成本。

【讨论】:

  • 这既是一个深思熟虑的答案,直接说明了 OP 的意图,也很好地说明了为什么应该关闭它。虽然这里对所涉及的权衡有很好的论据(我的 +1 是为了节省时间在评论中写下这一切),但除了 Guido 的权衡之外,没有什么可以明确回答“为什么 python 不这样做?”这个问题。
  • 我不同意应该关闭这个问题:这个答案显然不是基于意见的,而是(非常好)详细说明了为什么会出现这种选择的程序约束。
  • @MichaelDelgado。谢谢。我要补充一点,Guido 并没有真正说到这一点。这更像是冯诺依曼的决定。而实际上,连他自己都没有真正下定决心,因为这是显而易见的。同样,就像使用相同的 8 位来编码 255 和 -1。不仅仅是比喻。一个无符号的 NaN 必须是 255。我们不能在整数的可能值中有空洞。出于同样的原因,带符号的 NaN 必须是 -128 或 +127。最好是-128,为了对称。所以有符号的 NaN 必须与无符号的 NaN 不同地表示。否则世界将不得不放弃 -1≡255 的东西。
  • 如果没有它,ALU 将需要两倍以上的晶体管。我当然是在夸大其词,因为 ALU,尤其是现在,比 ADD、SUB 或 MUL 做的更多。但是这些操作需要以两种版本存在,一种用于签名,一种用于未签名。因为,如果我们有 int NaN,我们就不能再使用 2 补码了。这只是问题之一。
  • 这个答案夸大了情况。对于八位整数,可能很难为 NaN 牺牲一个值,但问题通常询问整数类型,而不仅仅是八位整数。对于 16 位或 32 位整数,这不是一种牺牲。并且将 1000000000000000 用于 NaN 将为带符号的 32 位二进制补码整数中的可表示值带来对称性。正如 chux 的回答所述,这更多是在市场上经过尝试和迷失的问题。目前尚不清楚,对于现代硬件,整数 NaN 是否无益,如果再次尝试,能否在市场上赢得一席之地。
【解决方案2】:

为什么不存在“NaN 整数”?

不值得。格式是达尔文式的——只有最好的才能生存。见证 1 的补码、符号大小、填充的无符号类型、非 8、16、32、64 等宽度的丢失。

几乎不需要 NAN 整数类型,语言反映了这一点。

请注意,垂死的补码和符号幅度整数编码在 C 中可能具有 -0 或“陷阱表示或正常值”。此陷阱可能会影响整数 NAN,但没有人要求这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 2012-03-09
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2013-05-05
    相关资源
    最近更新 更多