c# 安全地比较浮点预处理器定义

1wnzp6jl  于 2023-05-05  发布在  C#
关注(0)|答案(1)|浏览(280)

为了检测C实现是将long double视为double还是另一种类型,我检查了<float.h>的预处理器定义(即:LDBL_*DBL_*)。其中一些是整数文字,其他的是浮点文字。当比较浮点数时,我得到了典型的 “比较浮点数与==或!= is unsafe”(我总是启用这个警告,因为它很有用)。
然后我想在预处理器上执行比较,但是它不能处理浮点字面值比较,所以这似乎不是一个选择。
即使启用了-Wfloat-equal警告,我是否可以比较浮点字面值而不收到任何警告?如何执行?(测试是在运行时执行还是由预处理器执行都没有关系)。
我更喜欢C90或C99解决方案,但如果这是不可能的,后C99解决方案也将受到欢迎。

5w9g7ksd

5w9g7ksd1#

不需要比较浮点常量,因为它们完全由浮点类型的整数参数确定,除了DBL_HAS_SUBNORMLDBL_HAS_SUBNORM为−1的不可靠情况。(在这种情况下,DBL_TRUE_MINLDBL_TRUE_MIN将是不可靠的,因此比较它们将不可靠地指示类型是否具有相同的行为。
在下面的例子中,BFLT_RADIXfloatdoublelong double的基数相同),d 是基数-b 数字 b−1,并且在基数点之后有DBL_MANT_DIG数字。描述了DBL常数,并且LDBL常数类似。
DBL_MAX等于0.ddd... ddd·B**e,其中 eDBL_MAX_EXP
DBL_MIN等于0.100...000·B**e,其中 eDBL_MIN_EXP
DBL_TRUE_MIN等于DBL_MIN或0.000...001·B**e,其中 eDBL_MIN_EXP,分别取决于DBL_HAS_SUBNORM是0还是1。
DBL_EPSILON等于0.000...001·B**e,其中 e 为1。
因此,比较整数参数提供了比较浮点常量所提供的所有信息。
如果需要比较浮点常量,选项包括:

  • a == b替换为! (a < b || a > b)
  • 将比较放在一个单独的翻译单元中,并在没有-Wfloat-equal的情况下编译它。
  • 使用Clang而不是GCC,因为Clang在比较浮点常量表达式时似乎不会发出警告,即使启用了-Wfloat-equal

相关问题