简体   繁体   English

这为什么有效? (在c ++中找到奇数)

[英]why does this work? (finding odd number in c++)

for (unsigned int i = 1; i <= 100; i++) {
    if (i & 0x00000001) {
        std::cout << i<<",";
    }
}

why does (and how): if( i & 0x00000001 ) figure out the odd number? 为什么(以及如何): if( i & 0x00000001 )算出奇数?

0x00000001 is 1 in binary, although it's written in hexadecimal (base-16) notation. 0x00000001是二进制1 ,尽管它是用十六进制(base-16)表示法编写的。 That's the 0x part. 这是0x部分。

& is the bit-wise 'AND' operator, which is used to do binary digit (bit) manipulations. &是一个按位'AND'运算符,用于执行二进制数字(位)操作。

i & 1 converts all of the binary digits of i to zero, except for the last one. i & 1i & 1所有二进制数字转换为零,除了最后一个。

It's straightforward to convert the resulting 1-bit number to a boolean, for evaluation by the if statement. 将得到的1位数转换为布尔值,直接用if语句进行求值。

The following chart shows the last 16 binary digits of i, and what happens to them. 下图显示了i的最后16位二进制数字,以及它们发生了什么。

i:   i in binary:        i & 1 in binary:    convert to boolean
---- ------------------- ------------------- ---------------------
1    0000000000000001    0000000000000001    true
2    0000000000000010    0000000000000000    false
3    0000000000000011    0000000000000001    true
4    0000000000000100    0000000000000000    false
5    0000000000000101    0000000000000001    true
6    0000000000000110    0000000000000000    false
7    0000000000000111    0000000000000001    true
8    0000000000001000    0000000000000000    false
...  ...                 ...                 ...
99   0000000001100011    0000000000000001    true
100  0000000001100100    0000000000000000    false

It's using a bitwise "and" operator to mask off all but the last bit. 它使用按位“和”运算符来屏蔽除最后一位之外的所有内容。 If the last bit is a 1, the number is odd. 如果最后一位是1,则该数字是奇数。 Is that enough explanation? 那是否足够解释?

When we look at numbers in base 10, it's easy to tell if a number is divisible by 10: it has a 0 in the last position. 当我们查看基数为10的数字时,很容易判断一个数字是否可以被10整除:它在最后一个位置有一个0。 The code above looks at the digit in the last position as well, but in base 2. If it's non-zero, the number is not divisible by 2. 上面的代码也会查看最后一个位置的数字,但是在基数2中。如果它不为零,则该数字不能被2整除。

It masks off the last bit. 它掩盖了最后一点。 If you look at each place in the binary representation of a number (..., 256, 128, 64, 32, 16, 8, 4, 2, and 1), you'll notice that only the one's place is odd. 如果你看一个数字(...,256,128,64,32,16,8,4,2和1)的二进制表示中的每个地方,你会注意到只有一个地方是奇数。 All the rest of the places have an even value whether the bits are set or cleared (zero being even). 无论位是置位还是清零(零均为偶数),所有其余位置都具有偶数值。 And adding even numbers will always give an even number. 添加偶数将始终给出偶数。 Only that last one's place determines the parity of the number. 只有最后一个位置才能确定数字的奇偶校验。 The i & &0x00000001 part just isolates that last one's place. i & &0x00000001部分只是隔离了最后一个位置。

You are doing bitwise comparison. 你正在做逐位比较。 The if bit0 AND bit0 are both 1, then the answer's bit0 = 1. if bit0 AND bit0都是1,那么答案的bit0 = 1。

Seeing that &0x00000001 is 1, any numbers with this bit are odd. 看到&0x00000001为1,具有该位的任何数字都是奇数。

0x00000001 = 1
0x00000010 = 2
0x00000011 = 3
etc.

So, if you do a bitwise AND 所以,如果你做一个按位AND

00000001 AND 
00000001 = 
00000001 (same as true)

00000010 AND 
00000001 = 
00000000 (same as false)

00000011 AND 
00000001 = 
00000001 (same as true)

etc

Odd numbers are all numbers of the form (2*n+1) where n is any integer (-2,-1,0,1....). 奇数是形式的所有数字(2 * n + 1),其中n是任何整数(-2,-1,0,1 ......)。 So to find an odd number you have to see if the integer you're working with has that '+1' on it. 所以要找到一个奇数,你必须看看你正在使用的整数是否有'+1'。 When stored as an unsigned integer, a number can be expressed as the sum of powers of 2: 2^0 + 2^1 +2^2 + 2^4, etc. The binary version of the unsigned integer looks like a truth map of sorts: for every place there's a '1' in the binary number, add that power of two to the number. 当存储为无符号整数时,数字可以表示为2:2 ^ 0 + 2 ^ 1 + 2 ^ 2 + 2 ^ 4等的幂的总和。无符号整数的二进制版本看起来像真值图各种各样:对于每个地方,二进制数中都有一个“1”,将该数字加到该数字上。 So, if you start at the right most digit in the binary representation of the unsigned integer and move left, each digit represents a power of two. 因此,如果从无符号整数的二进制表示中的最右边的数字开始并向左移动,则每个数字表示2的幂。 If the digit is 1 then you add that power of two to the running sum and when you reach the end of the binary number. 如果数字为1,则将2的幂加到运行总和以及到达二进制数的末尾时。

Thus: 10001110b can be converted into an integer by summing the powers of two: 因此:10001110b可以通过对两个幂的求和来转换为整数:

Rightmost: 2^1 + 2^2 + 2^3 + 2^7 :Leftmost = 141 最右边:2 ^ 1 + 2 ^ 2 + 2 ^ 3 + 2 ^ 7:最左边= 141

The trick is that the rightmost digit represents 2^0. 诀窍是最右边的数字代表2 ^ 0。 This is always 1. All the other digits represent even numbers. 这始终是1.所有其他数字代表偶数。 So, in terms of odd numbers you have to find the '+1'. 所以,就奇数而言,你必须找到'+1'。 That corresponds to the rightmost digit. 这对应于最右边的数字。 All the other digits represent numbers of the form '2*n'. 所有其他数字代表'2 * n'形式的数字。 Therefore, to determine if a number of this format (unsigned integer) is odd you need only see if the right most bit is '1'. 因此,要确定此格式 (无符号整数)的数量是否为奇数,您只需要查看最右边的位是否为“1”。

The operation performed on the unsigned integer is a logical AND operation. 对无符号整数执行的操作是逻辑AND操作。 Anything AND'd with 0 is 0, and 1 AND'd with 1 is 1. So the operation will cause all binary digits in the unsigned integer representation to be 0 except for the binary digit representing 2^0 (which is 1). 与0的任何AND与0为1,与1的1与1为1.因此,除了表示2 ^ 0(即1)的二进制数字之外,该操作将使无符号整数表示中的所有二进制数字为0。 So the unsigned integer binary representation will boil down to 0x00000001 if it's odd and 0x00000000 if it's even. 所以无符号整数二进制表示如果是奇数则会归结为0x00000001,如果是偶数则会归结为0x00000000。

Note: When I write 0x00000000, the '0x' means that it's hexadecimal format. 注意:当我写0x00000000时,'0x'表示它是十六进制格式。 Each '0' represents four bits. 每个“0”代表四位。 So 0x00 is hexadecimal for 00000000b Written out in binary, the resulting possible unsigned integer binary representations after AND'ing the unsigned integer are: 所以对于00000000b,0x00是十六进制以二进制写出,在对无符号整数进行AND运算后得到的可能的无符号整数二进制表示为:

00000000000000000000000000000000b == 0 and 00000000000000000000000000000001b == 1 00000000000000000000000000000000b == 0和000000000000000000000000000000000001b == 1

Before I say the following, I'll first say that I pretty much always use the bit test to determine whether an int is odd or even. 在我说下面之前,我首先会说我几乎总是使用位测试来确定int是奇数还是偶数。

But, strictly speaking, you should use (i % 2) or ((i % 2) != 0) to determine is i is odd. 但是,严格地说,你应该使用(i % 2)((i % 2) != 0)来确定i是奇数。 This will work regardless of the represenation of negative numbers, while on a one's complement machine (-3 & 0x01) will return zero (a false result) even though clearly it's odd. 无论负数的表示如何,这都会起作用,而在一个补码机器上(-3和0x01)将返回零(一个错误的结果),即使它显然是奇数。

I realize that machiens that use something other than two's complement to represent negative number are very,very rare nowadays, but it's also true that compilers nowadays will universally compile (i % 2) to a bit test anyway. 我意识到,使用除了两个补码以外的东西来代表负数的机器人现在非常非常罕见,但是现在编译器也会普遍编译(i % 2)到一点测试。 And remember, I usually don't follow my own advice here, so that's might be an indication of the true value of this suggestion. 请记住,我通常不会在这里遵循自己的建议,因此这可能表明了这一建议的真正价值。

The bitwise AND operator follows this truth table for every bit: 按位AND运算符跟随每个位的真值表:
0 & 0 = 0 0&0 = 0
0 & 1 = 0 0&1 = 0
1 & 0 = 0 1&0 = 0
1 & 1 = 1 1&1 = 1

Since computers work with numbers in base 2 and each bit represents a power of two value (1,2,4,8,16 ..), 由于计算机使用基数为2的数字,每个位代表两个值的幂(1,2,4,8,16 ..),
the least significant bit represents the only odd number, regardless how big or small the value is, and regardless whether it is signed or unsigned. 最低有效位代表唯一的奇数,无论值有多大或多小,无论是有符号还是无符号。 Since the resulting bit is only set if both operands have that bit set, the result is true if and only if the number is odd. 由于仅在两个操作数都设置了该位时才设置结果位,因此当且仅当数字为奇数时,结果才为真。

Example: 0b1110101 1 = 示例:0b1110101 1 =
(1 * 2^0) + (1 * 2^1) + (0 * 2^2) + (1 * 2^3) + (1 * 2 ^ 0) +(1 * 2 ^ 1)+(0 * 2 ^ 2)+(1 * 2 ^ 3)+
(0 * 2^4) + (1 * 2^5) + (1 * 2^6) + (1 * 2^7) = (0 * 2 ^ 4)+(1 * 2 ^ 5)+(1 * 2 ^ 6)+(1 * 2 ^ 7)=
1 + 2 + 0 + 8 + 0 + 32 + 64 + 128 = 235 1 + 2 + 0 + 8 + 0 + 32 + 64 + 128 = 235
Without the least significant bit set, the value would be 234 and hence an even number. 如果没有设置最低有效位,则该值将为234,因此为偶数。

For Example how we make a Binary Equivalent 例如,我们如何制作二元等价物

8 4 2 1 8 4 2 1

0 0 0 0 = 0 0 0 0 0 = 0

0 0 0 1 = 1 0 0 0 1 = 1

0 0 1 0 = 2 0 0 1 0 = 2

0 0 1 1 = 3 0 0 1 1 = 3

So you can see for any odd no. 所以你可以看到任何奇怪的没有。 LSB is always set , Same you check :) LSB总是设置,同样你检查:)

I hope my answer is clear 我希望我的回答很清楚

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM