无符号整数的差异-标准的支持方式来获得有符号结果? [英] difference of unsigned integer - standard supported way to get signed result?

查看:59
本文介绍了无符号整数的差异-标准的支持方式来获得有符号结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有两个任意时间戳记:

assuming two arbitrary timestamps:

uint32_t timestamp1;    
uint32_t timestamp2;

除了转换为更大的带符号类型的明显变体和相当冗长的if-else之外,是否有一种标准的一致方式来获得两者的带符号的区别.

Is there a standard conform way to get a signed difference of the two beside the obvious variants of converting into bigger signed type and the rather verbose if-else.

事先不知道哪个更大,但是知道相差不超过最大20位,因此它将适合32位带符号.

Beforehand it is not known which one is larger, but its known that the difference is not greater than max 20bit, so it will fit into 32 bit signed.

int32_t difference = (int32_t)( (int64_t)timestamp1 - (int64_t)timestamp2 );

此变体的缺点是,硬件可能不支持使用64位算术,当然只有存在较大的类型(时间戳已经是64位的情况下)时,才有可能使用.

This variant has the disadvantage that using 64bit arithmetic may not be supported by hardware and is possible of course only if a larger type exists (what if the timestamp already is 64bit).

其他版本

int32_t difference;
if (timestamp1 > timestamp2) {
  difference =    (int32_t)(timestamp1 - timestamp2);
} else {
  difference = - ((int32_t)(timestamp2 - timestamp1));
}

非常冗长,涉及条件跳转.

is quite verbose and involves conditional jumps.

那就是

int32_t difference = (int32_t)(timestamp1 - timestamp2);

从标准的角度来看,这是否可以保证正常工作?

Is this guaranteed to work from standards perspective?

推荐答案

您可以基于

使用union类型pun

You can use a union type pun based on

typedef union
{
    int32_t _signed;
    uint32_t _unsigned;
} u;

unsigned算术执行计算,将结果分配给_unsigned成员,然后读取union_signed成员作为结果:

Perform the calculation in unsigned arithmetic, assign the result to the _unsigned member, then read the _signed member of the union as the result:

u result {._unsigned = timestamp1 - timestamp2};
result._signed; // yields the result

这对于任何实现我们所依赖的固定宽度类型的平台都是可移植的(它们不需要).对于有符号成员,保证2的补码,并且在机器"级别,2的补码有符号算术与无符号算术没有区别.这里没有转换或memcpy类型的开销:一个好的编译器将编译出本质上是标准的语法糖.

This is portable to any platform that implements the fixed width types upon which we are relying (they don't need to). 2's complement is guaranteed for the signed member and, at the "machine" level, 2's complement signed arithmetic is indistinguishable from unsigned arithmetic. There's no conversion or memcpy-type overhead here: a good compiler will compile out what's essentially standardese syntactic sugar.

(请注意,这是C ++中的未定义行为.)

(Note that this is undefined behaviour in C++.)

这篇关于无符号整数的差异-标准的支持方式来获得有符号结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆