精华内容
下载资源
问答
  • 妙用异或运算取反

    千次阅读 2020-08-15 17:09:38
    取反是平时使用频率非常高的一项逻辑操作,最常见的做法是使用if判断来实现。使用if自然没有什么问题,硬要说的话,就是“不够优雅”。但是我个人觉得所谓的“优雅”其实是玄学,代码可以追求简洁,但没必要执着。 ...

    取反是平时使用频率非常高的一项逻辑操作,最常见的做法是使用if判断来实现。使用if自然没有什么问题,硬要说的话,就是“不够优雅”。但是我个人觉得所谓的“优雅”其实是玄学,代码可以追求简洁,但没必要执着。

    下面分享的是一个比较“懒”的取反方法,利用了异或运算。知识点缺失的请自行百度。

    $a = 1;
    $b = $a ^ 1;
    

    这个方法还可以直接运用到 mysql 上

    UPDATE `table` SET isshow = isshow ^ 1 WHERE id =1
    
    展开全文
  • 最近看源码,复习了下基础运算知识,做下记录,一些表述与其他或者官方有些诧异,纯属个人心得,欢迎参考借鉴,指出错误,共勉。 public static void main(String[] args) { 一、左移运算 //左移: 简单的理解为 移...

    最近看源码,复习了下基础运算知识,做下记录,一些表述与其他或者官方有些诧异,纯属个人心得,欢迎参考借鉴,指出错误,共勉。

        public static void main(String[] args) {
    
            //正数左移: 简单的理解为 移几位就在右边加几个0依次计算
            System.out.println(3 << 1);//6 3乘以2的1次方 11 ==> 110 [4+2+0]
            System.out.println(3 << 2);//12 3乘以2的2次方 11 ==> 1100 [8+4+0+0]
            System.out.println(3 << 3);//24 3乘以2的3次方 11 ==> 11000 [16+8+0+0+0]
            System.out.println(3 << 4);//48 3乘以2的4次方 11 ==> 110000 [32+16+0+0+0+0]
            System.out.println(3 << 5);//96 3乘以2的5次方 11 ==> 1100000 [64+32+0+0+0+0+0]
    
            //负数左移: 先获取补码,低位补0,高位超出舍弃,再取移位后的反码,再取补码[最终结果],以上操作符号位都不变
            //原码 ==> 反码 ==> 补码 ==> 移位 ==> 再取反码 ==> 再取补码(最终结果)
            System.out.println(-7 << 3);  //-56
            /*
            原码 1000 0000 0000 0000 0000 0000 0000 0111
            反码 1111 1111 1111 1111 1111 1111 1111 1000 [符号位不变,按位取反]
            补码 1111 1111 1111 1111 1111 1111 1111 1001 [符号位不变,反码+1]
            移位 1111 1111 1111 1111 1111 1111 1100 1000 [*符号位不变,高位超出位舍弃,低位补0]
       再取反码  1000 0000 0000 0000 0000 0000 0011 0111 [符号位不变,按位取反]
       再取补码  1000 0000 0000 0000 0000 0000 0011 1000 [符号位不变,反码+1]
             */
    
            System.out.println(-297 << 5); //-9504
            /*
            原码 1000 0000 0000 0000 0000 0001 0010 1001
            反码 1111 1111 1111 1111 1111 1110 1101 0110 [符号位不变,按位取反]
            补码 1111 1111 1111 1111 1111 1110 1101 0111 [符号位不变,反码+1]
            移位 1111 1111 1111 1111 1101 1010 1110 0000 [*符号位不变,高位超出位舍弃,低位补0]
       再取反码  1000 0000 0000 0000 0010 0101 0001 1111 [符号位不变,按位取反]
       再取补码  1000 0000 0000 0000 0010 0101 0010 0000 [符号位不变,反码+1]
             */
    
            //正数右移(有符号右移): 简单的理解为 移几位 左边就删几位0依次计算
            System.out.println(96 >> 1);//48 96除以2的1次方 1100000 ==> 0110000 [0+32+16+0+0+0+0]
            System.out.println(96 >> 2);//24 96除以2的2次方 1100000 ==> 0011000 [0+0+16+8+0+0+0]
            System.out.println(96 >> 3);//12 96除以2的3次方 1100000 ==> 0001100 [0+0+0+8+4+0+0]
            System.out.println(96 >> 4);//6 96除以2的4次方 1100000 ==> 0000110 [0+0+0+0+4+2+0]
            System.out.println(96 >> 5);//3 96除以2的5次方 1100000 ==> 0000011 [0+0+0+0+0+2+1]
    
    
            //负数右移 : 获取反码 => 补码 => 移位[符号位不变,高位补1,低位超出位舍弃] => 再取移位后的反码 =>取移位后的补码
            System.out.println(-56 >> 3); //-7
            /*
              原码 1000 0000 0000 0000 0000 0000 0011 1000
              反码 1111 1111 1111 1111 1111 1111 1100 0111 [符号位不变,按位取反]
              补码 1111 1111 1111 1111 1111 1111 1100 1000 [符号位不变,反码+1]
              移位 1111 1111 1111 1111 1111 1111 1111 1001 [*符号位不变,高位补1,低位超出位舍弃]
         再取反码  1000 0000 0000 0000 0000 0000 0000 0110 [符号位不变,按位取反]
         再取补码  1000 0000 0000 0000 0000 0000 0000 0111 [符号位不变,反码+1](最终结果)
             */
    
            System.out.println(-139 >> 5); //-5
            /*
              原码 1000 0000 0000 0000 0000 0000 1000 1011
              反码 1111 1111 1111 1111 1111 1111 0111 0100 [符号位不变,按位取反]
              补码 1111 1111 1111 1111 1111 1111 0111 0101 [符号位不变,反码+1]
              移位 1111 1111 1111 1111 1111 1111 1111 1011 [*符号位不变,高位补1,低位超出位舍弃]
         再取反码  1000 0000 0000 0000 0000 0000 0000 0100 [符号位不变,按位取反]
         再取补码  1000 0000 0000 0000 0000 0000 0000 0101 [符号位不变,反码+1](最终结果)
             */
    
            //正数无符号右移
            //有符号右移:正数的符号位为0,移动时,符号位不动,高位补0
            //无符号右移:高位补0,符号位跟随移动,符号位移动后也未0,
            //其实和有符号位移所得结果是一样的,所以宏观上将,正数的有符号位移和无符号位移是没啥区别的
            System.out.println(200 >> 5); //6
            /*
              原码 [0]000 0000 0000 0000 0000 0000 1100 1000
              移位 [0]000 0000 0000 0000 0000 0000 0000 0110
             */
            System.out.println(200 >>> 5); //6
            /*
              原码 [0]000 0000 0000 0000 0000 0000 1100 1000
              移位 0000 0[0]00 0000 0000 0000 0000 0000 0110
             */
    
            //负数无符号右移
            System.out.println(-200 >>> 5); //134217721
            /*
            原码 1000 0000 0000 0000 0000 0000 1100 1000
            反码 1111 1111 1111 1111 1111 1111 0011 0111 [符号位不变,按位取反]
            补码 1111 1111 1111 1111 1111 1111 0011 1000 [符号位不变,反码+1]
            移位 0000 0111 1111 1111 1111 1111 1111 1001 [*符号位也要偏移, 高位补符号位0, 低位超出位数舍弃](符号位变为0,为正数,三码合一,不用继续转换)(最终结果)
             */
    
            System.out.println(-9 >>> 4); //268435455
            /*
            原码 1000 0000 0000 0000 0000 0000 0000 1001
            反码 1111 1111 1111 1111 1111 1111 1111 0110 [符号位不变,按位取反]
            补码 1111 1111 1111 1111 1111 1111 1111 0111 [符号位不变,反码+1]
            移位 0000 1111 1111 1111 1111 1111 1111 1111 [*符号位也要偏移, 高位补符号位0, 低位超出位数舍弃](符号位变为0,为正数,三码合一,不用继续转换)(最终结果)
             */
    
            //或运算 & 规则 :都为1时才为1
            System.out.println(5 | 6); //值:7
            /* 5: 101
               6: 110
            或值: 111 ==> [4+2+1] ==> 7
             */
            System.out.println(520 | 20); //值:540
            /* 520: 1000001000
                20:   0000010100
            或值:   1000011100 ==> [512+0+0+0+0+16+8+4+0+0] ==>  540
             */
    
            //与运算 | 规则:有一个为1,则为1
            System.out.println(5 & 6); //值:7
            /* 5: 101
               6: 110
            与值: 100 ==> [4+0+0] ==> 4
             */
            System.out.println(520 & 20); //值:0
            /* 520: 1000001000
                20: 0000010100
            或值:   0000000000 ==> [0+0+0+0+0+0+0+0+0+0] ==>  0
             */
    
            System.out.println(88 & 66); //值:0
            /* 88: 1011000
               66: 1000010
             或值: 1000000 ==> [64+0+0+0+0+0+0] ==>  64
             */
    
            //异或运算  ^ 规则:不同为1(左边补0不做计算)
            System.out.println(5 ^ 6); //值:3
            /* 5: 101
               6: 110
           异或值: 011 ==> [0+2+1] ==> 3
             */
             System.out.println(520 ^ 20); //值:540
            /* 520: 1000001000  => 0111110111
                20: 0000010100  =>      01011
             异或值: 1000011100 ==> [512+0+0+0+0+16+8+4+0+0] ==>  540
             */
    
             System.out.println(88 ^ 66); //值:0
            /* 88: 1011000
               66: 1000010
            异或值: 0011010 ==> [0+0+16+8+0+2+0] ==>  26
             */
    
            //取反运算 ~ 规则:按位取反
            // 正数步骤 原码取反(值1) ==> 值1-1[符号位不变](值2) ==> 再取反[符号位不变](值3) ==> 转成10进制[注意符号位:1负数;0正数]
            System.out.println(~7); // -8
            /*
            7: 0000 0000 0000 0000 0000 0000 0000 0111
          取反:1111 1111 1111 1111 1111 1111 1111 1000   负数的补码
        求反码:1111 1111 1111 1111 1111 1111 1111 0111  补码减1 ()
    再取反得原码:1000 0000 0000 0000 0000 0000 0000 1000 得原码
    符号位为1 确定值为负数;1000 转为10进制为8 ===> -8
             */
    
            System.out.println(~9); //-10
            /*
    原码、反码、补码: 0000 0000 0000 0000 0000 0000 0001 0001
               取反: 1111 1111 1111 1111 1111 1111 1110 1110
        减一获得补码: 1111 1111 1111 1111 1111 1111 1110 1101
          取反得原码: 1000 0000 0000 0000 0000 0000 0001 0010
             */
    
            System.out.println(~88); //-89
            /*
    原码、反码、补码: 0000 0000 0000 0000 0000 0000 0101 1000
               取反: 1111 1111 1111 1111 1111 1111 1010 0111
               减一: 1111 1111 1111 1111 1111 1111 1010 0110
             再取反: 1000 0000 0000 0000 0000 0000 0101 1001
             */
             
            /**
             * 负数二进制的三种表现形式
             * 1.原码: 绝对值的二进制(符号位为1)
             * 2.反码: 原码取反(符号位不参与运算)
             * 3.补码: 取反之后 + 1
             */
    // 负数步骤 转成原码(绝对值原码符号位为1) ==> 原码取反(值1) ==> 值1+1[符号位不变](值2) ==> 再取反[符号位不变](值3) ==> 转成10进制[注意符号位:1负数;0正数]
            System.out.println(~-9); //8
            /*
          原码: 1000 0000 0000 0000 0000 0000 0000 1001
          取反: 0111 1111 1111 1111 1111 1111 1111 0110
          加一: 0111 1111 1111 1111 1111 1111 1111 0111
        再取反: 0000 0000 0000 0000 0000 0000 0000 1000
             */
    
            System.out.println(~-7); //6
            /*
          原码: 1000 0000 0000 0000 0000 0000 0000 0111
          取反: 0111 1111 1111 1111 1111 1111 1111 1000
          加一: 0111 1111 1111 1111 1111 1111 1111 1001
        再取反: 0000 0000 0000 0000 0000 0000 0000 0110
             */
    
            System.out.println(~-88); //87
            /*
             原码: 1000 0000 0000 0000 0000 0000 0101 1000
             取反: 0111 1111 1111 1111 1111 1111 1010 0111
             加一: 0111 1111 1111 1111 1111 1111 1010 1000
           再取反: 0000 0000 0000 0000 0000 0000 0101 0111
             */
    
        }
    
    展开全文
  • 逻辑运算(按位取反

    千次阅读 2019-07-28 19:08:17
    按照我平时的理解,当我使用按位取反运算的时候,计算机会将操作数所对应的二进制表达式的每一个位进行取反计算,取反后所得到的值就是按位取反运算结果(这点没问题) 例如,假如我的计算机是32位的,我接下来要...

    (按位取反)运算的理解:

    按照我平时的理解,当我使用按位取反运算的时候,计算机会将操作数所对应的二进制表达式的每一个位进行取反计算,取反后所得到的值就是按位取反的运算结果(这点没问题)

    例如,假如我的计算机是32位的,我接下来要计算~5的值,计算过程如下:

    5 的二进制表达式为:0000 0000 0000 0000 0000 0000 0000 0101

    执行运算,即5后: 1111 1111 1111 1111 1111 1111 1111 1010,即结果为-6

    以上过程没有任何问题,但我们如果忘记了负数的二进制表达方式,那么就会对这个结果产生疑问,为什么1111 1111 1111 1111 1111 1111 1111 1010表示-6,可能我们会以为它应该表示-10等等,所以,理解~按位取反的另一个关键就是理解1111 1111 1111 1111 1111 1111 1111 1010为什么表示-6,也即理解负数的二进制表达方式。

    现在计算机普遍使用补码表示负数。知道一个数的补码,要求其值的方法是:首先看符号位也就是最左的一位,如果是1代表是负数(-)如果是0代码是正数(+),然后对该值取反再+1,得到其源码。

    例如本例中得到的 1111 1111 1111 1111 1111 1111 1111 1010,其符号位(最左一位)是1,表明它表示的是负数,欲求其源码,需先对其取反,然后再加1:0000 0000 0000 0000 0000 0000 0000 0101 + 1 = 0000 0000 0000 0000 0000 0000 0000 0110,然后在得到的源码前加一个负号,即-0000 0000 0000 0000 0000 0000 0000 0110 = -6。以上便是对按位取反运算以及负数的二进制表示的理解,不难发现,在求源码的时候,要将补码进行取反后再加1,然而这个补码原本就是之前由运算时,对原来的操作数通过~按位取反而得来的,所以,此时在求该补码的源码时的取反操作,相当于将补码变回了原来的那个操作数,之后进行的加1操作就相当于对原来的操作数进行加1,只不过结果变成了他的相反数。

    因此,可以总结出按位取反的计算结论是:n = -(n+1)

    例如本例中,~5 = -(5+1),即~5 = -6

    & 与 都是1为1

    | 或 有1就为1
    取反 1变0 0变1 ~227 = -228

    ^ 异或 相同为0 不同为1

    << 左移 左移补0

    右移 右移补符号位`

    #include <stdio.h>
    
    
    int main()
    {
    		//	&	与		都是1为1
    		//	|	或		有1就为1
    		//	~   取反		1变0 0变1
    		//	^	异或		相同为0 不同为1
    		//	<<	左移		左移补0
    		//	>>	右移		右移补符号位
    
    
    	int a = 1;
    	int b = 2;
    
    	a = a ^ b;
    	b = a ^ b;
    	a = a ^ b;
    
    	return 0;
    }
    
    展开全文
  • 本课主要讲解了逻辑比较中的近似等于和取反,重点是取反命令,通过取反命令控制按钮的标题,实现对MP3的播放暂停。 一、官方源码 近似等于 调用格式: 〈逻辑型〉 近似等于 (文本型 被比较文本,文本型 比较文本...

    本课主要讲解了逻辑比较中的近似等于和取反,重点是取反命令,通过取反命令控制按钮的标题,实现对MP3的播放暂停。

    一、官方源码

    近似等于
    调用格式: 〈逻辑型〉 近似等于 (文本型 被比较文本,文本型 比较文本) - 系统核心支持库->逻辑比较
    英文名称:like
    当比较文本在被比较文本的首部被包容时返回真,否则返回假,运算符号为“?=”或“≈”。本命令为初级命令。
    参数<1>的名称为“被比较文本”,类型为“文本型(text)”。
    参数<2>的名称为“比较文本”,类型为“文本型(text)”。

    操作系统需求: Windows、Linux
    取反
    调用格式: 〈逻辑型〉 取反 (逻辑型 被反转的逻辑值) - 系统核心支持库->逻辑比较
    英文名称:not
    如果参数值为真则返回假,如果参数值为假则返回真。本命令为初级命令。
    参数<1>的名称为“被反转的逻辑值”,类型为“逻辑型(bool)”。

    操作系统需求: Windows、Linux、Unix

    教程源码:

    511遇见(www.511yj.com)511遇见(www.511yj.com)

    511遇见(www.511yj.com)511遇见(www.511yj.com)

    .版本 2
    
    .程序集 窗口程序集_启动窗口
    .程序集变量 集_开关, 逻辑型
    
    .子程序 _按钮1_被单击
    .局部变量 a, 文本型
    .局部变量 b, 文本型
    
    a = 编辑框1.内容 ' 被比较文本
    b = 编辑框2.内容 ' 比较文本
    ' 当比较文本在被比较文本的首部被包容时返回真,否则返回假,运算符号为“?=”或“≈”。本命令为初级命令。
    信息框 (a ≈ b, 0, “近似等于返回的逻辑值”, )
    
    .子程序 _按钮2_被单击
    
    播放音乐4 ()
    
    .子程序 播放音乐1
    
    .如果 (按钮2.标题 = “播放”)
    播放MP3 (-1, 取运行目录 () + “\白月光.mp3”)
    按钮2.标题 = “暂停”
    .否则
    暂停播放MP3 ()
    按钮2.标题 = “播放”
    .如果结束
    
    .子程序 播放音乐2
    .局部变量 开关, 逻辑型, 静态
    
    ' 调试输出 (开关)
    开关 = 取反 (开关)
    ' 调试输出 (开关)
    .如果 (开关 = 真)
    播放MP3 (-1, 取运行目录 () + “\白月光.mp3”)
    按钮2.标题 = “暂停”
    .否则
    暂停播放MP3 ()
    按钮2.标题 = “播放”
    .如果结束
    
    .子程序 播放音乐3
    
    ' 调试输出 (开关)
    集_开关 = 取反 (集_开关)
    ' 调试输出 (开关)
    .如果 (集_开关)
    播放MP3 (-1, 取运行目录 () + “\白月光.mp3”)
    按钮2.标题 = “暂停”
    .否则
    暂停播放MP3 ()
    按钮2.标题 = “播放”
    .如果结束
    
    .子程序 播放音乐4
    
    集_开关 = 取反 (集_开关)
    按钮2.标题 = 选择 (集_开关, “暂停”, “播放”)
    .判断开始 (集_开关)
    播放MP3 (-1, 取运行目录 () + “\白月光.mp3”)
    .默认
    暂停播放MP3 ()
    .判断结束

    源码:易语言教程逻辑比较-取反(按钮播放暂停)

             511遇见易语言教程

    展开全文
  • 逻辑取反运算中, expression为-1或者+1,结果均为1;只有expression的值为0,结果才是1 #include <stdio.h> int main() { printf("\n\n\n逻辑取反运算,表达式判断测试\n"); int i=0; printf("i=%d, !i=...
  • !和~的区别(逻辑取反和按位取反)

    千次阅读 2019-01-12 21:36:20
    针对逻辑运算与按位运算区别如下: 针对这个问题,有一个经典的题目: int x=3; do { printf(" %d\n",x -=2);}while(!(–x)); 则上面的程序段,以下哪个选项正确( ) A.输出的是1 B.输出的是1和-...
  • 进制运算 1) ~取反 2) &与 &与计算(逻辑计算) 基本规则:有0则0 ​ 0 & 0 = 0 ​ 0 & 1 = 0 ​ 1 & 0 = 0 ​ 1 & 1 = 1 计算时,需要将两个数字对其位数,对应位置计算与计算 例子: ...
  • 逻辑运算

    2019-08-30 13:33:12
    逻辑运算 布尔数只有0,1两种值,表示真,假,通常用于...逻辑运算有三种:+,×,取反+,\times,\text{取反}+,×,取反 运算方式如下: {0+0=00+1=11+0=11+1=1 \begin{cases} 0+0=0 \\ 0+1=1 \\ 1+0=1 \\ 1+1=1 \end{case...
  • 逻辑运算指令

    2021-04-04 11:33:22
    目录(1)逻辑运算指令(2) 算术逻辑移位指令(3) 循环移位指令 (1)逻辑运算指令 ① NOT 取反指令 (Logical Not) NOT ② ADN 逻辑与运算 (Logical And) AND ③ OR 逻辑或指令 (Logical OR) OR 目标, 源 ④...
  • 逻辑运算与位运算

    2021-03-30 17:47:08
    逻辑运算 package com.xu.operator; //逻辑运算符 public class Demo5 { public static void main(String[] args) { //与(and) 或(or) 非(取反) boolean a=true; boolean b=false; System.out.println("a&...
  • 参加运算的两个数据,按二进制位进行“与”运算运算规则: 0&0=0; 0&1=0; 1&0=0; 1&1=1; 即:两位同时为“1”,结果才为“1”,否则为0 例如:3&5 即 0000 0011& ...
  • 位级运算 一般将十六进制的参数扩展成二进制表示然后进行位级运算再转换为...逻辑运算只有两种结果:非零参数表示为true,参数0表示为false,他们返回1或0。 逻辑运算符: &&:与 ||:或 !:取反 ...
  • 12.1 位运算 C语言具有位逻辑运算和移位运算的独特功能参与位运算的运算量必须是整数位逻辑运算包括&|四种运算移位运算有>两种运算其中位单目运算符 12.1.1 按位与 12.1.2 按位或 12.1.3 按位异或 12.1.4 按位取反 ...
  • 逻辑运算和位运算

    2016-06-05 23:19:00
    逻辑运算是指表达式返回值的运算,值只有真与假;位运算是指数值转换为二进制后的位运算,每位是0或1。逻辑运算符: 与运算:&& 或运算:|| 非运算: ! 位运算符: 按位与:& 按位或 | 取反: ~ 右移:>> ...
  • 位运算与逻辑运算

    2020-07-30 19:28:50
    位运算 位运算符,&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)。 位运算符只对整数型进行操作。位运算是将数据先转化为二进制...逻辑运算只对逻辑值操作,通常1
  • JavaScript 逻辑运算

    2019-10-05 13:20:38
    逻辑运算可以将多个比较操作放在一起进行比较。 运算符 辑运算符 名称 说明 && 逻辑与 检查多个条件,如果被检查的条件都返回true则返回true || 逻辑或 检查多个条件,如果被检查的...
  • JavaScript逻辑运算运算符 这些写都是我在网上学习的关于逻辑运算符知识跟着视频所整理的资料 /* * JS中的提供了三种逻辑逻辑运算关系 * * * * ! 非 * -!非可以用来对一个值进行非运算 * -所谓的非运算就是...
  • Oracle逻辑运算

    2021-06-09 09:19:49
    逻辑运算 在 WHERE 子句之中是可以同时编写多个条件的,但是这多个条件之间就必须使用逻辑连接,主要使用两种符号: ·AND:条件 AND 条件 AND 条件;  所有条件都要同时满足 ·OR:条件 OR 条件 OR 条件;  ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,083
精华内容 433
关键字:

逻辑运算取反