有符号整数溢出 [英] signed integer overflow

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

问题描述

我在clc ++上问了这个,但是他们建议大家可以更好地回答。


基本上,我正在尝试编写代码检测有符号整数溢出

math。我试图尽可能高效,而不使用

汇编语言,并且不会导致未定义的行为。那当然,

意味着在它发生之前捕获溢出。


我问的是(剥离与C ++的任何相关性):


如果整数类型的范围在零左右不对称(即2'的补偿),是否可以安全地假设额外的值(s)是一个

否定的一面?


原因是我目前认为这可能是最简单的数学运算

无符号,检查溢出,然后修复标志。我会处理

的事实,即范围可能在零附近不对称作为角落情况。


我从C ++小组的人那里学到了什么:


1)C和C ++标准在签名/未签名

值的处理上是等价的。我曾经想过(错误地,我猜)他们略有不同。


2)标准(应该总是大写?),C ++至少,

只允许三种格式:1'的comp。,2'的comp。和符号/幅度。我没有意识到这一点,并且认为任何格式都是允许的,而且我担心我的代码在一些奇怪的格式上正常工作我从来没有<听说过
。如果这是真的,那么我唯一的角落案例在2'的补码中,最大值为b $ b(大小)负值。


我以为这是一个被打死的问题在

语言中,但我在网上找不到任何内容。嗯,那不是真的。

我发现的东西总是假设已签名的溢出行为很好并且

作为无符号工作。


这里不相关,但我试图写一个类模板,

表现得像Ada的远程类型(和子类型)。也就是说,例如,如果X

+ Y溢出或超出其指定的范围,它将抛出

例外。


谢谢,


REH

I asked this on c.l.c++, but they suggested you folks may be better able to
answer.

Basically, I am trying to write code to detect overflows in signed integer
math. I am trying to make it as efficient as possible without resorting to
assembly language, and without causing undefined behavior. That, of course,
means catching the overflow before it happens.

What I asked was (stripping any relevance to C++):

If the range of an integer type is not symmetrical around zero
(i.e., 2''s comp.), is it safe to assume that the extra value(s) is one
the negative side?

The reason is I am currently thinking it may be easiest to do the math as
unsigned, check for overflow, and then fixup the sign. I would handle the
fact that the range may not be symmetrical around zero as a corner case.

What I learned from the folks on the C++ group:

1) C and C++ Standards are equivalent on the treatment of signed/unsigned
values. I had thought (mistakenly, I guess) that they differed slightly.

2) That the Standard (should that always be capitalized?), C++ at least,
allows only three formats: 1''s comp., 2''s comp., and sign/magnitude. I
didn''t realize this and thought that any format was allowed, and I was
worried about my code working correctly on some weird format I''ve never
heard of. If that is true, then my only "corner case" is with the maximum
(in magnitude) negative value in 2''s complement.

I had thought this was a problem that had been beaten to death in both
languages, but I could find nothing on the web. Well, that''s not true. The
stuff I did find always assumed that signed overflow was well behaved and
worked as unsigned.

Not relevant here, but I am attempting to write a class template that
behaves like Ada''s ranged types (and subtypes). That is, for example, if X
+ Y overflows or strays out of its assigned range, it will throw an
exception.

Thanks,

REH

推荐答案

REH写道:
REH wrote:
如果整数类型的范围在零附近不对称(即2'的comp。),可以安全地假设额外的值是一个
消极方面?


是的。标准清楚地表明有符号整数类型由

符号位组成,至少有一定数量的值位(15为短int和

int,以及31(长),并且至少为零填充位。因为有符号整数类型的非负值的

表示与无符号整数类型相同

,所以很容易看出最多可以存在/>
只有一个额外的值,并且该值必须为负值,因为必须设置符号

位才能获得额外的位组合。想想

(异端!)三位整数,其中第一个是符号位:


位模式无符号值有符号值

000 0 0

001 1 1

010 2 2

011 3 3


所有剩余的值都必须设置为高位,因此必须为带符号类型的负值

(无论它是''是补码,还是两个'') >
补充,或sign-and-mag)。

我从C ++小组的人那里学到的东西:

1)C和C ++标准是等价的关于签名/未签名
值的处理。我曾经想过(错误地,我猜)他们有点不同。


不,他们相当于TTBOMKAB。

2)标准(应该总是大写?),至少是C ++,只允许三种格式:1'的comp。,2'的comp。和sign / magnitude。
If the range of an integer type is not symmetrical around zero
(i.e., 2''s comp.), is it safe to assume that the extra value(s) is one
the negative side?
Yes. The Standard makes it clear that signed integer types are made up of a
sign bit, at least a certain number of value bits (15 for short int and
int, and 31 for long), and at least zero padding bits. Because the
representation of non-negative values of signed integer types is the same
as for unsigned integer types, it is easy to see that there can be at most
only one "extra" value, and that value must be negative because the sign
bit will have to be set in order to get the extra bit combination. Think of
(heretical!) three-bit ints, with the first of them being the sign bit:

Bit pattern Unsigned value Signed value
000 0 0
001 1 1
010 2 2
011 3 3

All remaining values must have the high bit set, and thus must be negative
in a signed type (irrespective of whether it''s ones'' complement, two''s
complement, or sign-and-mag).
What I learned from the folks on the C++ group:

1) C and C++ Standards are equivalent on the treatment of signed/unsigned
values. I had thought (mistakenly, I guess) that they differed slightly.
No, they''re equivalent TTBOMKAB.

2) That the Standard (should that always be capitalized?), C++ at least,
allows only three formats: 1''s comp., 2''s comp., and sign/magnitude.




对C来说也是一样的


-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

邮件:rjh在上面的域名



It''s the same for C.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
mail: rjh at above domain


REH写道:

.. .. snip ...
如果整数类型的范围在零附近不对称(即2'的comp。),可以安全地假设额外的值
原因是我目前认为将数学作为无符号,检查溢出,然后修复符号可能是最容易的。我会处理这样一个事实,即范围可能不是对称的,因为角落的情况是零。
.... snip ...
If the range of an integer type is not symmetrical around zero
(i.e., 2''s comp.), is it safe to assume that the extra value(s)
is one the negative side?

The reason is I am currently thinking it may be easiest to do the
math as unsigned, check for overflow, and then fixup the sign. I
would handle the fact that the range may not be symmetrical around
zero as a corner case.




无需猜测。对于任何整数类型,限制值为< limits.h>中的限制值。


-

"如果您想通过groups.google.com发布后续内容,请不要使用

损坏的回复链接在文章的底部。点击

" show options"在文章的顶部,然后点击

回复在文章标题的底部。 - Keith Thompson



No need to guess. For any integer type, the limiting values are
available in <limits.h>.

--
"If you want to post a followup via groups.google.com, don''t use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson


Richard Heathfield写道:
Richard Heathfield wrote:
[...]想想
(异端!)三位整数,第一个是符号位:

位模式无符号值有符号值
000 0 0
001 1 1
010 2 2
011 3 3

所有剩余的值必须设置为高位,因此必须是带符号类型的负数(不管它是否是'补码,两个'是
补充,或签名和mag)。
[...] Think of
(heretical!) three-bit ints, with the first of them being the sign bit:

Bit pattern Unsigned value Signed value
000 0 0
001 1 1
010 2 2
011 3 3

All remaining values must have the high bit set, and thus must be negative
in a signed type (irrespective of whether it''s ones'' complement, two''s
complement, or sign-and-mag).




100可能为零,这不是负面的:


if(minus_zero< 0 || minus_zero> 0 || minus_zero!= 0){

puts(这不是C!);

puts((否则减零是一个陷阱表示,\ n"

of undefined behavKUHYTDjn; lkUy97609i] *& ^%



100 could be zero, which is not negative:

if (minus_zero < 0 || minus_zero > 0 || minus_zero != 0) {
puts("This isn''t C!");
puts("(Or else minus zero is a trap representation,\n"
"and you''re only seeing this as a consequence\n"
"of undefined behavKUHYTDjn;lkUy97609i]*&^%


这篇关于有符号整数溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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