是否有任何(有效的)C实现,其中float不能表示值0?

use*_*289 5 c floating-point

如果所有浮点数都表示为x = (-1)^s * 2^e * 1.m,则在没有特殊情况支持的情况下无法存储零.

Kei*_*son 8

不,所有符合C的实现都必须支持浮点值0.0.

浮点模型在C标准的 5.2.4.2.2节中描述(链接是最近的草案).该模型不会使有效数据中的前导1(有时称为尾数)隐含,因此它没有问题表示0.0.

大多数二进制浮点的实现都不存储前导1,实际上是你在问题中引用的公式:

x = (-1)^s * 2^e * 1.m
Run Code Online (Sandbox Code Playgroud)

通常是正确的(尽管e存储方式可能不同).

在包括IEEE的这种实现中,使用特殊情况比特模式(通常是全比特零)来表示0.0.

根据评论中的讨论,tmyklebu认为并非所有由5.2.4.2.2中的浮点模型定义的数字都必须是可表示的.我不同意; 如果不是所有这些数字都需要可表示,那么该模型几乎是无用的.但即使抛开这个论点,也有一个0.0必须具有代表性的明确要求.N1570 6.7.9第10段:

如果未显式初始化具有静态或线程存储持续时间的对象,则:

  • ...
  • 如果它有算术类型,则初始化为(正或无符号)零;
  • ...

这是一个非常长期的要求.1975年C参考(K&R1出版前3年)说:

未明确初始化的任何外部定义对象的初始值保证为0.

这意味着必须有一个可表示的0值.K&R1(1978年出版)说,第198页:

未初始化的静态和外部变量保证从0开始; 未初始化的自动和寄存器变量保证以垃圾开始.

有趣的是,1990 ISO C标准(相当于1989 ANSI C标准)略逊于其前身和后继者.在6.5.7中,它说:

如果没有显式初始化具有静态存储持续时间的对象,则会隐式初始化它,就好像每个具有算术类型的成员都被赋值为0,并且每个具有指针类型的成员都被赋予空指针常量.

如果具有用于确切表示不要求一个浮点类型0.0,那么"分配0"短语将意味着从一转换int0的浮点型,得到一个小的值接近0.0.尽管如此,C90具有与C99和C11相同的浮点模型(但没有提到次正规或非标准化值),我上面关于模型数的论证仍然适用.此外,C90标准正式被C99取代,后者又被C11取代.