如何用环绕或溢出减去两个无符号整数 [英] How to subtract two unsigned ints with wrap around or overflow

查看:176
本文介绍了如何用环绕或溢出减去两个无符号整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要减去两个无符号整数(x和y)。 x总是大于y。但是,x和y都可以环绕;例如,如果它们都是字节,则在0xff之后变为0x00。问题是如果x环绕,而y则没有。现在x似乎小于y。幸运的是,x不会缠绕两次(只保证一次)。假设字节,x已经包装并且现在是0x2,而y没有并且是0xFE。 x - y的正确答案应该是0x4。



可能,

 (x> y)? (x-y):( x + 0xff-y); 

但我认为还有另一种方式,涉及2s赞美?在这个嵌入式系统中,x和y是最大的unsigned int类型,因此添加0xff ...是不可能的



编写语句的最佳方法是什么(目标语言是C)?<假设有两个无符号整数:




  • 如果你知道一个人应该比另一个人更大,那就减去。它可以工作,前提是你没有多次缠绕(显然,如果你有,你将无法分辨)。

  • 如果你不知道那个是大于另一个,将结果减去并转换为具有相同宽度的signed int。如果两者之间的差异在signed int的范围内(如果没有,你将无法分辨),它将起作用。



澄清一下:原始海报描述的场景似乎令人困惑,但典型的是单调增加固定宽度计数器,例如硬件计数器计数器或协议中的序列号。计数器(例如8位)0xfc,0xfd,0xfe,0xff,0x00,0x01,0x02,0x03等,你知道你拥有的两个值x和y,x后来出现。如果x == 0x02且y == 0xfe,则计算xy(作为8位结果)将给出4的正确答案,假设减去两个 n 位值包装模2 < sup> n - C99保证减去无符号值。 (注意:C标准保证此行为可以减去签名的值。)


There are two unsigned ints (x and y) that need to be subtracted. x is always larger than y. However, both x and y can wrap around; for example, if they were both bytes, after 0xff comes 0x00. The problem case is if x wraps around, while y does not. Now x appears to be smaller than y. Luckily, x will not wrap around twice (only once is guaranteed). Assuming bytes, x has wrapped and is now 0x2, whereas y has not and is 0xFE. The right answer of x - y is supposed to be 0x4.

Maybe,

( x > y) ? (x-y) : (x+0xff-y);

But I think there is another way, something involving 2s compliment?, and in this embedded system, x and y are the largest unsigned int types, so adding 0xff... is not possible

What is the best way to write the statement (target language is C)?

解决方案

Assuming two unsigned integers:

  • If you know that one is supposed to be "larger" than the other, just subtract. It will work provided you haven't wrapped around more than once (obviously, if you have, you won't be able to tell).
  • If you don't know that one is larger than the other, subtract and cast the result to a signed int of the same width. It will work provided the difference between the two is in the range of the signed int (if not, you won't be able to tell).

To clarify: the scenario described by the original poster seems to be confusing people, but is typical of monotonically increasing fixed-width counters, such as hardware tick counters, or sequence numbers in protocols. The counter goes (e.g. for 8 bits) 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03 etc., and you know that of the two values x and y that you have, x comes later. If x==0x02 and y==0xfe, the calculation x-y (as an 8-bit result) will give the correct answer of 4, assuming that subtraction of two n-bit values wraps modulo 2n - which C99 guarantees for subtraction of unsigned values. (Note: the C standard does not guarantee this behaviour for subtraction of signed values.)

这篇关于如何用环绕或溢出减去两个无符号整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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