【问题标题】:Implementation-independent floating-point/integer conversions与实现无关的浮点/整数转换
【发布时间】:2019-11-06 21:59:34
【问题描述】:

假设I 是某个整数类型,F 是某个(实)浮点类型。

我想写两个函数。第一个函数应采用I 类型的值i 并返回一个布尔值,指示转换为Fi 是否属于可表示范围,即(F)i 是否具有已定义的行为。

第二个函数应取F 类型的值f 并返回一个布尔值,指示转换为If 是否属于可表示范围,即(I)f 是否将具有已定义的行为。

是否有可能编写这样一个函数,在每个符合标准的实现上,对任何输入都是正确的并且不会表现出未定义的行为?特别是我不想假设浮点类型是 IEEE 754 类型。

我分别询问 C 和 C++ 以及它们各自的标准版本,以防改变答案。

基本上,这个问题的目的是在完全不依赖 IEEE 754 或其他标准或硬件细节的情况下确定(明智的)浮点/整数转换是否可行。我好奇地问。

与例如比较INT_MAXFLT_MAX 似乎是不可能的,因为在不知道哪种类型的范围更广的情况下,不清楚在哪种类型中进行比较。

【问题讨论】:

  • std::numeric_limits 应该为您提供所有您需要知道的值是否可转换的信息(需要计算)。
  • @NathanOliver-ReinstateMonica 我不确定我应该使用什么进行比较。正如我所提到的,我认为我无法与max 进行比较,因为这已经需要将操作数转换为该类型,这可能是不可能的。我可以将整数的 log2 与 max_exponent 进行比较,但我不确定当它们比较相等时我能得出任何结论。
  • @GreenTree 谢谢,我一定是搜索了错误的术语。这个问题和其他相关的问题似乎是重复的。不过,我仍然需要详细阅读它们。
  • 只进行双向转换并检查是否相等有什么问题吗?我很难想到会失败的案例。

标签: c++ c language-lawyer


【解决方案1】:

some floatsome int 相当简单,我们可以假设 FLT_RADIX != 10 (2N 浮点数) 和 FP 的范围超出整数范围。

形成准确的 FP 限制
测试 FP 是否有一个 0** 的小数部分。 (也处理 NaN、inf)
测试是否太积极。
测试是否太消极。
测试是否转换为整数值轮次。

伪代码

// For now, assume 2's complement.
// With some extra macro magic, could handle all integer encodings. 

// Use integer limits whose magnitudes are at or 1 away from a power-of-2  
//   and form FP power-of-2 limits 
// The following will certainly not incur any rounding
#define FLT_INT_MAXP1 ((INT_MAX/2 + 1)*2.0f)
#define FLT_INT_MIN (INT_MIN*1.0f)

status float_to_int_test(float f) {
  float ipart;
  if (modff(f, &ipart) != 0.0) {
    return not_a_whole_number;
  }
  if (f >= FLT_INT_MAXP1) return too_big;
  if (f < FLT_INT_MIN) return too_negative;
  if (f != (volatile float) f)) return rounding_occurred;
  return success;
}

用上面的 float_to_int 测试武装......

status int_to_float_test(int i) { 
  volatile float f = (float) i;
  if (float_to_int_test(f) != success) return fail
  volatile int j = (int) f;
  if (i != j) return fail;
  return success;
}

可以进行简化,但要开始 OP。

需要额外代码的极端情况包括int128_t 或范围比floatFLT_RADIX == 10 更大的范围。


** 嗯 - 看起来 OP 不关心小数部分。在这种情况下,conversion from double to int 似乎是解决一半问题的好副本。

【讨论】:

  • 是的,我对小数部分不感兴趣。我认为I 的范围可能大于F 的情况是有问题的。链接的问题并没有完全回答这个问题,但我想可能被认为是重复的。如果有人想将其作为重复项关闭,我可以。
  • @uneven_mark 是的,“我比 F 大”很棘手 - 我稍后会添加一些内容 - 现实生活正在召唤我。 int double_to_int(double val, int *err) 确实处理“对小数部分不感兴趣”。
猜你喜欢
  • 2023-04-08
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多