一元减去的语义 [英] Semantics of unary minus

查看:96
本文介绍了一元减去的语义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我现在已经潜伏在clc几个月了,并希望从

开始,感谢这里的常客们开启我的眼睛是一个全新的维度

的知道c。考虑到我从来没有触及过一年前的标准,虽然我毕业于嵌入式软件开发......


无论如何,对于手头的问题:我最近在工作中偶然发现了以下

构造,并且无法真正决定

标准对此事的看法。


int a;

unsigned int b;


if(a< 0){

b = -a;

}


当'的值为-32768时,我无法确定这是否有效(承认

16位整数)。我看不出标准'对一元减去

语义的措辞如何允许2'的补语不对称。 C99说:


"一元运算符的结果是其(推广)

操作数的负数。整数提升在操作数上执行,

结果具有提升类型。 (与一元加上的语义相比,我对价值的消失感到有点怀疑......)


除非我我错了,不会被提升(成为一个整数),所以可能没有这样的事情,因为它的(推广的)操作数的负面影响?我觉得

就像标准告诉我,我最终可能得到一个值为32768的int ...

(仍然假设16位整数)?或者我应该考虑有隐含的

if-it-fits-otherwise-overflow?


我找不到任何帮助谷歌或常见问题解答,所以我真的很赞赏b $ b谢谢任何澄清。


Marc

解决方案

" Marc" <无**** @ mail.com>在消息中写道

news:ds ************* @ news.t-online.com ...

int a;
unsigned int b;

if(a< 0){
b = -a;
}

我当'的值为-32768(承认16位整数)时,无法确定这是否有效。我无法看到标准'对一元减去语义的措辞如何允许2'的补语不对称。 C99说:




-a溢出并且通常会产生-32768没有陷阱

(虽然实现不必)。转换

是2 ^ 16 - 32768,这是32768.所以你好运。


转换为无符号长不能很好地工作。

写b = 0U - a更安全相反。


PJ Plauger

Dinkumware,Ltd。
http://www.dinkumware.com


Marc写道:



我一直潜伏在clc上几个月了,并且想开始感谢
感谢这里的常客让我的眼睛睁开了一个全新的视野。知道c。考虑到我一年前从未触及标准,虽然我毕业于嵌入式软件开发......

无论如何,对于手头的问题:我偶然发现了以下情况
最近在工作中构建,并且无法真正决定
标准对此事的看法。

int a;
unsigned int b;

if(a< 0){
b = -a;
}

我无法决定这是否有效a'的值是-32768(承认16位整数)。我无法看到标准'对一元减去语义的措辞如何允许2'的补语不对称。 C99说:

"一元运算符的结果是其(提升的)操作数的否定。整数提升在操作数上执行,
结果具有提升类型。 (与一元加上语义相比,我对价值的消失有点怀疑......)

除非我弄错了,否则就赢了不被提升(成为一个int),因此可能没有其(推广)操作数的否定这样的事情?我觉得
就像标准告诉我,我最终可能得到一个值为32768的int ...
(仍然假设16位整数)?或者我应该考虑是否存在隐含的if-it-fits-otherwise-overflow?

我无法通过谷歌或常见问题解答找到任何帮助,所以我我真的很欣赏任何澄清。




是的,两个'的补码是零不对称的:那里

是绝对值不可表示的负数。

(标准实际上允许实施通过将所有1定义为陷阱表示来避免这种不对称性。

我从来没有听说过这样做的实现。)


然而,这并不意味着一元减去是不确定的:它'' s

只有在操作数的值不合适时才定义。这个

与二元减去的情况没什么不同:


"二元运算符的结果 - 运算符是区别

从第一个操作数减去第二个操作数产生的
。 (6.5.6 / 6)


这不是暗示所有减法必须

产生数学上正确的结果:`INT_MIN - 42'' ,对于

的例子,显然不会产生低于

INT_MIN的值。


当这种事情发生时,

标准的另一项条款接管:


如果在表达式的

评估期间发生_exceptional condition_ (也就是说,如果结果

没有在数学上定义,或者不在

类型的可表示值的范围内),行为是

undefined。 (6.5 / 5)


所以:如果你试图在`INT_MIN + INT_MAX'的系统上否定(或取绝对值)

INT_MIN '不是零,

C语言没有指明结果 - 任何事情都可能发生,

至少原则上。最常见的行为是忽略

溢出,结果表示(全部)

再次等于INT_MIN:INT_MIN是它自己在大多数情况下的否定
二进制补充系统。但是,这应该被认为是这些系统的怪癖,而不是C语言的一部分。


-

Eric Sosman
es*****@acm-dot-org.inva lid


Marc写道:

int a;
-a;
if-it-fits-otherwise-overflow?




是。

" overflow"就像在未定义的行为中一样。


这是琐事的一点,在写itoa时也会出现,

没有整数类型保证

能够代表INT_MIN的大小。


-

pete


Hi,

I''ve been lurking on clc for a few months now, and want to start by
thanking the regulars here for opening my eyes to a whole new dimension
of "knowing c". Considering I had never even touched the standards a
year ago, though I graduated in embedded SW development...

Anyway, to the problem at hand: I''ve stumbled upon the following
construct at work recently, and cannot really make up my mind about the
standard''s take on the matter.

int a;
unsigned int b;

if(a < 0) {
b = -a;
}

I just can''t decide if this is valid when a''s value is -32768 (admitting
16 bit ints). I can''t see how the standard''s wording on unary minus
semantics allows for 2''s complement asymmetry. C99 says:

"The result of the unary - operator is the negative of its (promoted)
operand. The integer promotions are performed on the operand, and the
result has the promoted type." (I''m also slightly suspicious about the
disappearance of "value" as compared to the semantics of unary plus...)

Unless I''m mistaken, a won''t be promoted (being an int), so there might
be no such thing as "the negative of its (promoted) operand"? I feel
like the standard tells me I might end up with an int worth 32768...
(still assuming 16 bit ints)? Or should I consider there is an implied
"if-it-fits-otherwise-overflow"?

I couldn''t find any help through google or in the FAQ, so I''d really
appreciate any clarification.

Marc

解决方案

"Marc" <no****@mail.com> wrote in message
news:ds*************@news.t-online.com...

int a;
unsigned int b;

if(a < 0) {
b = -a;
}

I just can''t decide if this is valid when a''s value is -32768 (admitting
16 bit ints). I can''t see how the standard''s wording on unary minus
semantics allows for 2''s complement asymmetry. C99 says:



-a overflows and typically yields -32768 without a trap
(though an implementation doesn''t have to). The conversion
is 2^16 - 32768, which is 32768. So you luck out.

Converting to unsigned long doesn''t work quite as well.
It is much safer to write "b = 0U - a" instead.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com


Marc wrote:

Hi,

I''ve been lurking on clc for a few months now, and want to start by
thanking the regulars here for opening my eyes to a whole new dimension
of "knowing c". Considering I had never even touched the standards a
year ago, though I graduated in embedded SW development...

Anyway, to the problem at hand: I''ve stumbled upon the following
construct at work recently, and cannot really make up my mind about the
standard''s take on the matter.

int a;
unsigned int b;

if(a < 0) {
b = -a;
}

I just can''t decide if this is valid when a''s value is -32768 (admitting
16 bit ints). I can''t see how the standard''s wording on unary minus
semantics allows for 2''s complement asymmetry. C99 says:

"The result of the unary - operator is the negative of its (promoted)
operand. The integer promotions are performed on the operand, and the
result has the promoted type." (I''m also slightly suspicious about the
disappearance of "value" as compared to the semantics of unary plus...)

Unless I''m mistaken, a won''t be promoted (being an int), so there might
be no such thing as "the negative of its (promoted) operand"? I feel
like the standard tells me I might end up with an int worth 32768...
(still assuming 16 bit ints)? Or should I consider there is an implied
"if-it-fits-otherwise-overflow"?

I couldn''t find any help through google or in the FAQ, so I''d really
appreciate any clarification.



Yes, two''s complement is asymmetric about zero: there
is a negative number whose absolute value is not representable.
(The Standard actually permits an implementation to dodge this
asymmetry by defining "all ones" to be a trap representation;
I''ve never heard of an implementation that does so.)

However, that doesn''t mean unary minus is undefined: it''s
only undefined if its operand has an inappropriate value. This
is really no different from the situation with binary minus:

"The result of the binary - operator is the difference
resulting from the subtraction of the second operand
from the first." (6.5.6/6)

This is not to be taken as implying that all subtractions must
produce mathematically correct results: `INT_MIN - 42'', for
example, is clearly not going to produce a value less than
INT_MIN.

When this sort of thing happens, another provision of the
Standard takes over:

"If an _exceptional condition_ occurs during the
evaluation of an expression (that is, if the result
is not mathematically defined or not in the range of
representable values for its type), the behavior is
undefined." (6.5/5)

So: If you try to negate (or take the absolute value of)
INT_MIN on a system where `INT_MIN + INT_MAX'' is not zero, the
C language does not specify the outcome -- anything can happen,
at least in principle. The commonest behavior is that the
overflow is ignored, and the resulting representation (all ones)
is equal to INT_MIN again: INT_MIN is its own negation on most
two''s-complement systems. However, this should be thought of
as a quirk of those systems, not as part of the C language.

--
Eric Sosman
es*****@acm-dot-org.invalid


Marc wrote:

int a; -a; "if-it-fits-otherwise-overflow"?



Yes.
"overflow" as in "undefined behavior".

It''s a point of trivia which also comes up when writing itoa,
that there is no integer type which is guaranteed
to be able to represent the magnitude of INT_MIN.

--
pete


这篇关于一元减去的语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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