Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 独立于实现的浮点/整数转换_C++_C_Language Lawyer - Fatal编程技术网

C++ 独立于实现的浮点/整数转换

C++ 独立于实现的浮点/整数转换,c++,c,language-lawyer,C++,C,Language Lawyer,假设I是某种整数类型,而F是某种(实)浮点类型 我想写两个函数。第一个函数应取类型为i的值i,并返回一个布尔值,指示转换为F的i是否属于可表示范围,即(F)i是否具有定义的行为 第二个函数应取类型为f的值f,并返回一个布尔值,指示转换为I的f是否属于可表示范围,即(I)f是否具有定义的行为 是否有可能编写这样一个函数,在每个符合标准的实现上都是正确的,并且对于任何输入都不会表现出未定义的行为?特别是,我不想假设浮点类型是IEEE 754类型 我分别询问C和C++以及它们各自的标准版本,如果改变了

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

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

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

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

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

基本上,这个问题的目的是要弄清楚(合理的)浮点/积分转换是否可能,而完全不依赖IEEE 754或其他标准或硬件细节。我问是出于好奇

与例如
INT\u MAX
FLT\u MAX
进行比较似乎是不可能的,因为在不知道哪种类型的范围更大的情况下,不清楚要在哪种类型中进行比较。

一些浮点到一些INT相当容易,因为我们可以假设
FLT\u基数!=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;
}

简化是可能的,但是要开始做一些事情

需要额外代码的极端情况包括
int128\u t
或范围大于
float
FLT\u基数==10



**Hmmm-似乎OP不关心分数部分。在这种情况下,对于一半的问题来说是一个很好的重复。

std::numeric_limits
应该为您提供所需的所有信息,以了解这些值是否可转换(需要进行计算)。@NathanOliver,我不确定应该使用什么进行比较。正如我提到的,我认为我无法与
max
进行比较,因为这已经需要将操作数转换为该类型,这可能是不可能的。我可以将整数的log2与
max_指数
进行比较,但我不确定当它们比较相等时是否能得出任何结论。相关的,甚至是一个duplicate@GreenTree谢谢,我一定是找错词了。这个问题和其他相关的问题似乎是重复的。但是我仍然需要详细阅读它们。仅仅做双向转换和检查相等性有什么问题吗?我很难想象这样做会失败。是的,我对分数部分不感兴趣。我认为,
I
的范围可能大于
F
的范围是有问题的。链接的问题并不能完全回答这个问题,但我想可以认为是重复的。如果有人想以复制品的形式关闭它,我会同意的。@U标记是的,“我比F的大”是很棘手的-我稍后会补充一些东西-现实生活正在召唤我离开。处理“对小数部分不感兴趣”。
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;
}