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

时间:2014-10-27 21:36:06

标签: c floating-point

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

3 个答案:

答案 0 :(得分:8)

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

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

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

x = (-1)^s * 2^e * 1.m

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

在包括IEEE的此类实现中,使用特殊情况位模式(通常为全位 - 零)来表示0.0

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

  

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

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

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

  

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

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

  

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

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

  

如果未初始化具有静态存储持续时间的对象   显式地,它被隐式初始化,好像每个成员都有   算术类型被赋值为0,每个成员都有指针类型   被分配了一个空指针常量。

如果浮点类型不需要具有0.0的精确表示,则"分配0"短语意味着从int0转换为浮点类型,产生一个小值 close 0.0。尽管如此,C90具有与C99和C11相同的浮点模型(但没有提及次正规或非标准化值),我上面关于模型数的论证仍然适用。此外,C90标准正式被C99取代,而C99又被C11取代。

答案 1 :(得分:2)

搜索一段时间后发现了这个。

ISO / IEC 9899:201x第6.2.5节,第13段

  

每个复杂类型都具有与数组相同的表示和对齐要求   类型恰好包含相应实数类型的两个元素;第一个要素是   等于复数的实部和虚部的第二个元素。

第6.3.1.7节,第1段

  

当真实类型的值转换为复杂类型时,复数的实部   结果值由转换为相应实数类型的规则确定   复数结果值的虚部是正零或无符号零。

所以,如果我理解这一点,任何支持C99(带有_Complex类型的第一个C标准)的实现都必须支持浮点值0.0。

修改 Keith Thompson指出复杂类型在C99中是可选的,所以这个论点毫无意义。

答案 2 :(得分:1)

我相信以下浮点系统是一个符合浮点运算的例子,没有零表示:

float是一个48位数,带有一个符号位,15个指数位和32个有效位。符号位,指数位和有效位的每个选择都对应于具有隐含前导1位的正常浮点数。

完成draft C standard Keith Thompson linked的第5.2.4.2.2节中的约束:

  • 这个浮点系统明显符合标准草案5.2.4.2.2的第1和第2段。
  • 我们只代表标准化数字;第3段只允许我们走得更远。
  • 第4段很棘手;它表示零和“不是浮点数的值”可以是有符号或无符号的。但是第3段并没有强迫我们拥有任何不是浮点数的值,所以我无法想象将第4段解释为要求零。
  • 第5段中可表示的值的范围显然是-0x1.ffffffffp+163830x1.ffffffffp+16383
  • 第6段指出+-*/和数学库具有实现定义的准确性。还行。
  • 只要我们能为所有常量找到合适的值,第7段并不真正限制此实现。
  • 我们可以将FLT_ROUNDS设置为0;这样,我甚至不必指定加法或减法溢出时会发生什么。
  • FLT_EVAL_METHOD应为0。
  • 我们没有次正规,因此FLT_HAS_SUBNORM应为零。
  • FLT_RADIX应为2,FLT_MANT_DIG为32,FLT_DECIMAL_DIG为10,FLT_DIG为9,FLT_MIN_EXP为-16383,{ {1}}应为-4933,FLT_MIN_10_EXP应为16384,FLT_MAX_EXP为4933。
  • 您可以使用FLT_MAX_10_EXPFLT_MAXFLT_EPSILONFLT_MIN