前置知识:

原码表示法是整数的一种简单的表示法,符号位用0表示正号,用1表示负号,数值一般用二进制形式表示。
整数的反码可由原码得到,如果是正数,则反码与原码一样;如果是负数,则反码是对它的原码(符号位除外)各位取反而得到的。
整数的补码可由原码得到。如果是正数,则补码与原码一样;如果是负数,则补码是在反码基础上,末位加1而得到。

(关于补码的知识,详见这里

~ 取反 (把运算数的各个二进制按位求反)

 

e.g.

1. ~9

原码:   0000 1001

(这里最左位的0表示正,如果是1就表示负,其余位按二进制表示)

反码:  0000 1001

(正数的反码等于它的原码)

补码:  0000 1001

(正数的补码等于它的原码)

按位取反:1111 0110

(这时得到的是取反后的补码,我们要把它转化成原码)

(因为第一位是1,所以这是负数,要按照负数的转换法则倒退回去)

(负数的反码+1=补码,因此负数的反码=补码-1)

反码:  1111 0101

(负数的原码按位取反(符号位除外)即为反码,因此负数的反码按位取反(符号位除外)就可转换为原码

原码:  1000 1010

转换为十进制,即为:  -10

 

2. ~-9

原码:  1000 1001

(最左位是1表示是负数)

反码:  1111 0110

(负数的原码转换为反码,符号位不变,其余位按位取反)

补码:  1111 0111

(负数的反码转换为补码,加1即可)

按位取反:0000 1000

(按位取反后为正数,因为正数的补码等于原码,所以直接转十进制即可)

转十进制,即为:  8

 

 

 

这时可以进入正题了。

 

1 for(int i=1;i<=n;i++)

 

这应该算写的最多的代码之一了,殊不知它还可以进行卡常优化。

 

for(int i=1;i<=n;i=-~i)

 

i=-~i等价于i++,但要比i++快上很多。

 

 

如何证明其正确性?

设i用二进制表示为:abcd efgh

a取反后为A

 

 

当i>=0时,a=0

原码:0bcd efgh

反码:0bcd efgh

补码:0bcd efgh

取反:1BCD EFGH

反码:1BCD EFGH -1

(这里-1就是将从右往左数第一个为1的数变为0,它右边所有的0变为1)

(所以在变为原码时,从右往左数第一个为0的数变为1,它右边所有的1变为0,其余位按位取反)

原码:1bcd efgh +1

这时转为十进制即为:-i-1

再取相反数即为:i+1

 

当i<0时,a=1

原码:1bcd efgh

反码:1BCD EFGH

补码:1bcd efgh -1

取反:0BCD EFGH +1

反码:0BCD EFGH +1

这时转为十进制即为:-i-1

再取相反数即为:i+1

 

证毕。

相关文章:

  • 2022-03-04
  • 2022-12-23
  • 2022-12-23
  • 2021-08-03
  • 2022-12-23
  • 2021-12-13
  • 2021-12-20
  • 2022-01-26
猜你喜欢
  • 2021-09-14
  • 2022-12-23
  • 2021-12-12
  • 2021-12-11
  • 2022-12-23
  • 2022-12-23
  • 2021-08-30
相关资源
相似解决方案