将有符号整数范围映射到无符号

pla*_*cel 5 c++ int integer c++11

我遇到一个问题,应该将有符号整数转换为unsigned,保留它们的范围和顺序.

鉴于以下定义:

#include <limits>

#define MIN(X) std::numeric_limits<X>::min();
#define MAX(X) std::numeric_limits<X>::max();
Run Code Online (Sandbox Code Playgroud)

将有符号范围[MIN(T),MAX(T)]映射到无符号范围[0,MAX(U)]的最快和最正确的方法是什么?

哪里:

T是有符号整数类型

U是无符号整数类型

sizeof(T)== sizeof(U)

我尝试了各种比特和数字方法来提出解决方案,但没有成功.

Moh*_*ain 7

unsigned int signedToUnsigned(signed int s) {
  unsigned int u =  1U + std::numeric_limits<int>::max();
  u += s;
  return u;
}
Run Code Online (Sandbox Code Playgroud)

这里有实例

这将添加signed_max + 1signed int确保[MIN(int), MAX(int)]映射到[0, MAX(unsigned int)]


为什么这个答案会正常工作并正确映射:

将有符号整数添加到无符号时,带符号的数字将提升为无符号类型.来自第4.7节[conv.integral]

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 n ,其中n是用于表示无符号类型的位数).[注意:在二进制补码表示中,此转换是概念性的,并且位模式没有变化(如果没有截断). - 尾注]

  • 引用标准的优秀解释. (2认同)