相关疑难解决方法(0)

是否通过C99中未指定的联合进行类型惩罚,并且它是否在C11中指定?

Stack Overflow问题的一些答案获取浮点数的IEEE单精度位建议使用union类型双关的结构(例如:将a的位float转换为a uint32_t):

union {
    float f;
    uint32_t u;
} un;
un.f = your_float;
uint32_t target = un.u;
Run Code Online (Sandbox Code Playgroud)

但是,uint32_t根据C99标准(至少草案n1124),联盟成员的值似乎未指定,其中第6.2.6.1.7节规定:

当值存储在union类型的对象的成员中时,对象表示的字节与该成员不对应但与其他成员对应的字节采用未指定的值.

C11 n1570草案至少有一个脚注似乎暗示不再是这种情况(见6.5.2.3中的脚注95):

如果用于读取union对象的内容的成员与上次用于在对象中存储值的成员不同,则将值的对象表示的适当部分重新解释为新类型中的对象表示形式在6.2.6中描述(一个过程有时被称为''punning'').这可能是陷阱表示.

但是,第C.6.6.1.7节中的案文与C11草案中的C99草案相同.

这种行为在C99下实际上是未指定的吗?它是否在C11中指定?我意识到大多数编译器似乎都支持这一点,但是知道它是在标准中指定还是只是一个非常常见的扩展会很好.

c c99 unions type-punning c11

58
推荐指数
3
解决办法
8770
查看次数

可以在便携式C中写入从double到int的转换

我需要编写函数double_to_int(double val, int *err),在可能的情况下,它会将double val转换为整数; 否则报告错误(NAN/INFs/OUT_OF_RANGE).

所以伪代码实现看起来像:

if isnan(val):
    err = ERR_NAN
    return 0
if val < MAX_INT:
    err = ERR_MINUS_INF
    return MIN_INT
if ...
return (int)val
Run Code Online (Sandbox Code Playgroud)

在SO上至少有两个类似的问题:在这个答案中它以足够干净的方式解决了,虽然它是C++解决方案 - 在C中我们没有signed int的可移植数字.在这个答案中,它解释了为什么我们不能只检查(val > INT_MAX || val < INT_MIN).

因此,我看到的唯一可能的清洁方式是使用浮点环境,但它被称为实现定义的功能.

所以我的问题是:有没有办法以double_to_int跨平台的方式实现功能(仅基于C标准,甚至不考虑支持IEEE-754的目标平台).

c floating-point standards

19
推荐指数
1
解决办法
677
查看次数

Boost或标准库是否提供了检查演员表是否无损的方法?

我正在寻找一个标准库或Boost函数,它可以无损地将一个数字转换为另一个原始类型,并以某种方式告诉我该演员是否无损(或者如果不是则抛出异常).这里有些例子:

auto x = lossless_cast<double>(1u); // ok, double can represent 1
auto x = lossless_cast<int>(1.2); // fail, int can't represent 1.2
auto x = lossless_cast<int>(1E200); // fail, int can't represent 1E200
Run Code Online (Sandbox Code Playgroud)

boost::numeric_cast接近的是,它将拾取掉落在目标类型的数值范围之外的强制转换,但如果它们是无损但目标类型则不会(参见我的第二个示例).

C语言有一个问题,它为这个问题提供了一些手动解决方案,但是我正在使用boost标准库解决方案,基本上具有以下功能:

template <typename out, typename in>
out lossless_cast(in in_value)
{
  out out_value = static_cast<out>(in_value);

  if (static_cast<in>(out_value) != in_value)
    throw; // some exception

  return out_value;
}
Run Code Online (Sandbox Code Playgroud)

这个功能是否存在?

c++ boost

6
推荐指数
1
解决办法
309
查看次数

检查float是否可以表示为整数类型

如何在不float通过强制转换调用未定义的行为的情况下检查a是否可以表示为整数类型?这是§4.9.1禁止的:

可以将浮点类型的prvalue转换为整数类型的prvalue.转换截断; 也就是说,丢弃小数部分.如果截断的值无法在目标类型中表示,则行为未定义,

对于C来说存在这个问题,但是接受的答案显然会导致未定义的行为(首先是通过简单的转换而后来通过使用联合黑客,这使得整个事情对我来说非常可疑).

我可以看到如何拥有一个完全兼容的解决方案,但实现定义(假设IEEE-754浮点数)也是可以接受的.

c++ undefined-behavior

5
推荐指数
1
解决办法
217
查看次数