按位与签署字符 [英] Bitwise AND on signed chars

查看:121
本文介绍了按位与签署字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,我已经读入的数据类型符号字符数组的文件。我无法改变这个事实。

I have a file that I've read into an array of data type signed char. I cannot change this fact.

我现在想做到这一点:<!code>((C [1] - 安培;将0xC0)及0x80的),其中 C [I] 是签署的人物之一。

I would now like to do this: !((c[i] & 0xc0) & 0x80) where c[i] is one of the signed characters.

现在,我从的 C99标准中说:每个[按位与]操作数应具有整型。

Now, I know from section 6.5.10 of the C99 standard that "Each of the operands [of the bitwise AND] shall have integral type."

和C99的规范的第6.5节告诉我:

And Section 6.5 of the C99 specification tells me:

一些运营商(单目运算符〜和二元运算符&LT;&LT;,>>,&安培;,^和|,
  统称为位运算符)应具有整型操作数。
  这些操作符返回
  依赖于整数的内部重新presentations值,
  因而有实现定义方面作为符号类型。

Some operators (the unary operator ~ , and the binary operators << , >> , & , ^ , and | , collectively described as bitwise operators )shall have operands that have integral type. These operators return values that depend on the internal representations of integers, and thus have implementation-defined aspects for signed types.

我的问题是双重的:


  • 因为我想从文件中的原始位模式工作,我怎么能转换/投我符号字符符号焦,这样的位模式保持不变?

  • Since I want to work with the original bit patterns from the file, how can I convert/cast my signed char to unsigned char so that the bit patterns remain unchanged?

是否有这些实现定义问题的任何地方(比如说为MVSC和GCC)?

Is there a list of these "implementation-defined aspects" anywhere (say for MVSC and GCC)?

或者,你可以采取不同的路线,并认为这将产生对中任意值符号和无符号的字符相同的结果[I]

Or you could take a different route and argue that this produces the same result for both signed and unsigned chars for any value of c[i].

当然,我会奖励给有关标准或权威文本引用和劝阻知情的猜测。

Naturally, I will reward references to relevant standards or authoritative texts and discourage "informed" speculation.

推荐答案

正如其他人所指出的,在所有的情形产生你的实现是基于二进制补码,并会给正是你期待的结果。

As others point out, in all likelyhood your implementation is based on two's complement, and will give exactly the result you expect.

不过,如果你担心涉及符号值的操作的结果,和所有你关心的是位模式,干脆直接转换为等效的无符号类型。结果标准下定义的:

However, if you're worried about the results of an operation involving a signed value, and all you care about is the bit pattern, simply cast directly to an equivalent unsigned type. The results are defined under the standard:


  1. ...

  1. ...

否则,如果新类型是无符号的值被重复地添加变换或
减去超过可重新$ P $在新型psented最大值多一个
直到该值是在新的类型的范围。

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

此基本上指定结果将是二的补重值presentation


This is essentially specifying that the result will be the two's complement representation of the value.

基本情况是,在二的补码的数学运算的结果是模两个(即,在类型比特的数量),而这又是完全等同于掩蔽掉的比特的相关数一些功率。和数字的补体是由两个电力减去的数字

Fundamental to this is that in two's complement maths the result of a calculation is modulo some power of two (i.e. the number of bits in the type), which in turn is exactly equivalent to masking off the relevant number of bits. And the complement of a number is the number subtracted from the power of two.

因此​​增加负值是相同的添加从该值由两块功率的多个不同的任何值。

Thus adding a negative value is the same as adding any value which differs from the value by a multiple of that power of two.

即:

        (0 + signed_value) mod (2^N)
==
      (2^N + signed_value) mod (2^N)
==
  (7 * 2^N + signed_value) mod (2^N)

等。 (如果你知道模,这应该是pretty不言而喻真)

etc. (if you know modulo, that should be pretty self-evidently true)

因此​​,如果你有一个负数,加入二的幂将使其正(-5 + 256 = 251),但底部N位将是完全相同的(0b11111011),它不会影响数学运算的结果。由于值被截断,以适应类型,则结果正是你预计随着即使结果'溢出'(二进制值,即你可能认为会发生,如果数字是积极入手 - 这包装也很好定义的行为)。

So if you have a negative number, adding a power of two will make it positive (-5 + 256 = 251), but the bottom 'N' bits will be exactly the same (0b11111011) and it will not affect the outcome of a mathematical operation. As values are then truncated to fit the type, the result is exactly the binary value you expected with even if the result 'overflows' (i.e. what you might think happens if the number was positive to start with - this wrapping is also well defined behaviour).

因此​​,在8位二进制补码:

So in 8-bit two's complement:


  • -5的相同251(即256 - 5) - 0b11111011

  • 如果您加30,和251,你会得到281.但是,这是大于256,和281 MOD 256等于25完全一样30日 - 5

  • 251 * 2 = 502 502 256 MOD 246 = 246和-10都是0b11110110。

同样,如果您有:

unsigned int a;
int b;

a - b == a + (unsigned int) -b;

引擎盖下,这种转换是不可能算术实施,肯定会从一个寄存器/值到另一个直转让,或者只是优化了完全的数学不加以区分符号和无符号(INTE CPU标志pretation是另外一回事,但是这是一个实现细节)。该标准的存在,以确保实现不承担起自己做一些事情,而不是怪,或者我想,对此没有使用补一些奇怪的建筑......

Under the hood, this cast is unlikely to be implemented with arithmetic and will certainly be a straight assignment from one register/value to another, or just optimised out altogether as the maths does not make a distinction between signed and unsigned (intepretation of CPU flags is another matter, but that's an implementation detail). The standard exists to ensure that an implementation doesn't take it upon itself to do something strange instead, or I suppose, for some weird architecture which isn't using two's complement...

这篇关于按位与签署字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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