如何安全地将无符号值转换为有符号值
How to safely convert unsigned value to signed?
正如我所读到的,在有符号算术中,有许多未定义行为的情况。因此,我更喜欢使用无符号算术计算结果(甚至是有符号的),这是在没有未定义的情况下指定的。
但是,当使用无符号算术获得结果时,最后一步,仍需转换为有符号值。
这是我写的代码,我的问题是代码是否按照规则工作,即它是否安全,不依赖于一些未定义/未指定的行为?
/*
function to safely convert given unsigned value
to signed result having the required sign
sign == 1 means the result shall be negative,
sign == 0 means the result shall be nonnegative
returns 1 on success, 0 on failure
*/
int safe_convert(unsigned value, int sign, int *result) {
if (sign) {
if (value > -(unsigned)INT_MIN) return 0; // value too big
if (!value) return 0; // cannot convert zero to negative int
*result = INT_MIN + (int)((-(unsigned)INT_MIN) - value);
} else {
if (value > (unsigned)INT_MAX) return 0; //value too big
*result = (int)value;
}
return 1;
}
最终,有没有一种更简单的方法,不依赖于未定义/未指定的行为并做同样的事情?
最终,有没有一种更简单的方法,不依赖于未定义的行为并做同样的事情?
short x = (short) value;
int y = (int) value;
但要确定要转换为哪种积分类型。 value
可能会超出所用签名类型的范围。
唯一可能有问题的值是 INT_MIN
。因此,我只会做类似的事情
int safe_convert(unsigned value, int sign, int *result) {
if (sign) {
if (value > -(unsigned)INT_MIN) return 0; // value too big
if (-(unsigned)INT_MIN > (unsigned)INT_MAX // compile constant
&&
value == -(unsigned)INT_MIN) // special case
*result = INT_MIN;
else *result = -(int)value;
} else {
if (value > (unsigned)INT_MAX) return 0; //value too big
*result = (int)value;
}
return 1;
}
我不认为要求负零的情况证明错误返回是合理的。
从无符号到有符号的转换不是未定义的,而是已定义的实现。摘自C++标准,第4.7章积分转换,第3段:
如果目标类型是有符号的,则如果该值可以在目标类型中表示(和 位域宽度);否则,该值由实现定义
因此,以下是定义的实现,在许多平台上正是您所期望的(环绕):
unsigned u = -1;
int i = (int)u;
当sign
为假(正数)时,条件都准备好了,当sign
为真(负数)时,情况很棘手。 所以而不是:
if (value > -(unsigned)INT_MIN) return 0; // value too big
*result = INT_MIN + (int)((-(unsigned)INT_MIN) - value);
建议
// 1st half is for 2's compliment machines
// 2nd half is for symmetric ints like 1's compliment and signed ints
// Optimization will simplify the real code to 1 compare
if ((((INT_MIN + 1) == -INT_MAX) && (value > ((unsigned)INT_MAX + 1u))) ||
(( INT_MIN == -INT_MAX) && (value > (unsigned)INT_MAX ))) return 0;
int i = (int) value;
*result = -i;
INT_MIN == -INT_MAX
测试可用于有条件地允许有符号零。
相关文章:
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 获取隐式转换溢出从无符号到已签名的警告
- 如何在保持其值的同时将 c++ 无符号字符变量转换为 char 变量
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- C ++中无符号位长度类型之间的隐式转换,即uint8_t,uint16_t
- 将浮点数转换为无符号字符数组并打印出来
- 如何在 C/C++ 中将无符号字符*转换为无符号字符数组?
- 将无符号转换为复杂<int>原因符号转换警告
- 如何解决隐式转换丢失整数精度:'size_t'(又名"无符号长")到'int'警告?
- 如何将带有十六进制值的 std::string 转换为 std::vector<无符号字符>
- 将无符号字符 C++ 转换为 C#
- C++:使用没有位移位的指针将无符号字符转换为无符号 int
- 为什么我可以隐式地将字符*转换为常量字符*,但不能将无符号字符*
- 整数类型应该显式转换(例如"int"到"无符号")还是只会增加混乱?
- 将字符串转换为无符号字符数组/字节数组
- 如何将字符串转换为无符号字符数组