php中按位取反~的理解

昨天晚上在看php书籍的时候,看到到了一个操作符“~”解释是按位取反操作符,因为平时用得不多所以对它不是很了解,所以顺便网上收了一下,感觉讲的不是特别清楚,所以我花了点时间研究了一下,终于有点成果,所以在此为大家分享一下,如果说的有误还请大家批评指出。好了,下面就来说说这个按位取反的运算方式。

首先按照操作元来划分操作符,比如:$a>$b、$a>$b?1:0。第一个表达式中操作元是两个分别是$a和$b,所以这被称为二元运算,依此,表达式二就是三元。因此按位取反也就是一元运算符如:$a=~$b;

其次我们要了解计算机运算时存储的数据是0,1这种二进制数据。并且是以源码的补码形式存储,下面引出三个概念:

源码:一个整数,按照绝对值大小转换成二进制数,最高位为符号位是需要保留的。最高位0表示正数,1表示负数,比如(-3:1000 0000 0000 0000 0000 0000 0000 0011)。

反码:就是源码的反转,最高符号位除外,其余的1变0,0变1。

补码:也就是计算机存储的数据,定义为源码的反码加1。 (注意:正数的补码也就是它源码本身)

这里还有一个东西需要说明,刚才在对源码进行阐述的时候看到-3这个数占了32位,我们就在考虑为什么是32位而不是其他的呢。其实我们可以了解到php5.X版本中整数的最大最小区间为-2e31到+2e31

其中有个符号位所以数值表达最高就是31次幂。在php的高版本中会达到64位也就是-2e63到+2e63,因为现在用的普片较多的版本就是5.X的版本所以就以32位二进制来讲。

好了,现在对概念都理解了,下面我们就来看看具体操作:

先来看代码运算结果

<?php
    $a = -3;
    $b = ~$a;
    var_dump($b);    // int 2
?>

上面是-3按位取反后得到2,我们用上面的理论来分析一下:

-3源码:1000 0000 0000 0000 0000 0000 0000 0011

反码:1111 1111 1111 1111 1111 1111 1111 1100

补码:1111 1111 1111 1111 1111 1111 1111 1101 (反码加1得到补码)

现在执行按位取反操作后:

补码:0000 0000 0000 0000 0000 0000 0000 0010

反码:0000 0000 0000 0000 0000 0000 0000 0010

源码:0000 0000 0000 0000 0000 0000 0000 0010

为什么执行按位取反后源码和补码相同?嗯,其实上面已经解释了,在源码进行补码转换的时候符号位是不变的。我们看到按位取反操作后补码的符号位为0表示正数,而正数的补码就是源码本身。所以源码十进制换算后就是2了,我想这个就清楚了吧!现在是否明白了呢。。。<谢谢大家支持,成长从博客开始>

时间: 2024-10-10 08:19:52

php中按位取反~的理解的相关文章

SQL SERVER 2005/2008 中关于架构的理解(二)

本文上接SQL SERVER 2005/2008 中关于架构的理解(一)      架构的作用与示例 用户与架构(schema)分开,让数据库内各对象不再绑在某个用户账号上,可以解决SQL SERVER 2000及以前版本中“用户离开公司"问题,也就是在拥有该对象的用户离开公司,或离开该职务时,不必要大费周章地更改该用户所有的对象属于新的用户所有.另外,也可让 DBA 在安装某个套装软件时,设置该套装软件所用的数据库对象都属于某个特定的架构,容易区别.也就是说,在单一数据库内,不同部门或目的的对

C#中Thread类中Join方法的理解(转载)

指在一线程里面调用另一线程join方法时,表示将本线程阻塞直至另一线程终止时再执行      比如 Java代码   using System; namespace TestThreadJoin { class Program { static void Main() { System.Threading.Thread x = new System.Threading.Thread(new System.Threading.ThreadStart(f1)); x.Start(); Console

JavaScript中的伪数组理解

看过jQuery源码的人都知道类数组对象,与我们熟知的arguments对象很像 构造一个类数组必须有两个条件 第一个条件:你必须给对象定义个splice方法,只要他是一个function就可以 第二个条件:就是赋值一个length属性,或者增加push,unshift,shift,pop其中任何一个方法,并且调用了一次. 当这两个条件同时满足那么当前的对象在控制台输出后跟数组的格式一模一样. 一般而言大部分都是这样构造一个类数组对象(jQuery就是这么干的).因为相比而言,这样更简洁,并且更

jquery中的mouseenter实现理解

说在前面:首先说一下两者之间的区别,假设当前元素为element,mouseover事件具有冒泡特性,也就是说无论鼠标是从别的元素移动到element或者是从element的子元素移动到element都会触发mouseover事件.对于mouseenter事件,该事件没有冒泡特性,也就是说只有鼠标穿过该事件的时候才会触发mouseenter,如果鼠标一直在element内部"游走",则不会触发mouseenter.具体的例子可以参考这个例子点击打开链接. 前提说完了,那么怎么使用mou

架构设计中服务层的简单理解

如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 在ddd设计中我们经常会提到服务层,服务层是什么?职责是什么?有什么好处?. 先看简单的层次图(注:这里并没有考虑其他多余的领域逻辑数据层存储,或者UOW这些细节) 我的理解是服务层是处于我的应用程序业务层和表现层之间的应用程序边界,边界可能是很薄的一层类设计或者是分布式服务网络跃点.它是一个与技术无关的名词.由表现层直接调用,契约,执行命令(修改状态(CUD))或者是查询返回dto(数据迁

ubuntu下关于profile和bashrc中环境变量的理解

(0) 写在前面 有些名词可能需要解释一下.(也可以先不看这一节,在后面看到有疑惑再上来看相关解释) 启动bash shell:就是启动一个bash shell进程,通常可以理解为打开一个终端.需要注意的是如果你在终端输入sh后会发现自己又进入另一个交互式界面,这个时候其实fork了一个shell 子进程,如果你在这个交互式界面又输入了一次sh,那么相当于fork的shell子进程又fork了一个shell子进程,这个时候就启动了三个bash shell进程. 输入exit或者ctrl-d可以退

Java中线程同步的理解 - 其实应该叫做Java线程排队

Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等. 当多个线程同时读写同一份共享资源的时候,可能会引起冲突.这时候,我们需要引入线程"同步"机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团. 同步这个词是从英文synchronize(使同时发生)翻译过来的.我也不明白为什么

android中Logcat的深层理解

Android的开发也可以归类为嵌入式设备的开发,即便不是嵌入式开发,依然要注意对内存和处理的使用.养成一个好的习惯对自己的帮助是很大的. 在Log的源码中可以看到这样的注释: The order in terms of verbosity, from least to most is * ERROR, WARN, INFO, DEBUG, VERBOSE. Verbose should never be compiled * into an application except during

专家坐堂:机器学习中对核函数的理解

专家坐堂:机器学习中对核函数的理解