相关疑难解决方法(0)

高效的无符号签名转换,避免实现定义的行为

我想定义一个带有unsigned intas参数的函数,并向参数返回一个int全等模UINT_MAX + 1.

第一次尝试可能如下所示:

int unsigned_to_signed(unsigned n)
{
    return static_cast<int>(n);
}
Run Code Online (Sandbox Code Playgroud)

但正如任何语言律师所知,从无符号转换为大于INT_MAX的已签名值是实现定义的.

我想实现这一点,以便(a)它只依赖于规范规定的行为; (b)它在任何现代机器上编译成无操作并优化编译器.

对于奇怪的机器......如果没有签名的int congruent将UINT_MAX + 1模数为unsigned int,那么假设我想抛出一个异常.如果有多个(我不确定这是否可能),那么就说我想要最大的一个.

好的,第二次尝试:

int unsigned_to_signed(unsigned n)
{
    int int_n = static_cast<int>(n);

    if (n == static_cast<unsigned>(int_n))
        return int_n;

    // else do something long and complicated
}
Run Code Online (Sandbox Code Playgroud)

当我不是一个典型的二元补充系统时,我并不太关心效率,因为我认为不太可能.如果我的代码成为2050年无所不在的符号量级系统的瓶颈,那么,我敢打赌,有人可以解决这个问题并对其进行优化.

现在,第二次尝试非常接近我想要的.尽管转换int为某些输入的实现定义,但是unsigned标准保证转换为保留模UINT_MAX + 1的值.所以条件确实检查我想要什么,它将在我可能遇到的任何系统上编译成什么.

但是......我仍然在int没有首先检查它是否会调用实现定义的行为.在2050年的一些假设系统中,它可以做谁知道什么.所以我想说我想避免这种情况.

问题:我的"第三次尝试"应该是什么样的?

回顾一下,我想:

  • 从unsigned int转换为signed int
  • 保留值mod UINT_MAX + 1
  • 仅调用标准强制行为
  • 在具有优化编译器的典型二进制补码机器上编译成无操作

[更新]

让我举一个例子来说明为什么这不是一个微不足道的问题.

考虑具有以下属性的假设C++实现:

  • sizeof(int) 等于4
  • sizeof(unsigned) 等于4
  • INT_MAX 等于32767
  • INT_MIN等于-2 …

c++ integer casting integer-overflow language-lawyer

83
推荐指数
3
解决办法
4万
查看次数

当我混合有符号和无符号类型时会发生什么?

我正在学习C++语言,我对类型转换有一些疑问,你能解释一下像这样的表达式会发生什么:

unsigned int u = 10; 
int a = -42; 
std::cout << u - a << std::endl;
Run Code Online (Sandbox Code Playgroud)

在这里我知道如果我在有两个数学运算符时应用规则,结果将是52.但我想知道当编译器将a转换为无符号值时会发生什么情况会产生一个临时的无符号类型,之后会发生什么?表达式现在应该是10 -4294967254.

c++ unsigned expression built-in-types

18
推荐指数
2
解决办法
6517
查看次数