浅谈 &0xFF操作

浅谈 &0xFF操作在java.io.FilterOutputStream.DataOutputStream:与机器无关地写入各种类型的数据以及String对象的二进制形式,从高位开始写。这样一来,任何机器上任何DataInputStream都能够读取它们。所有方法都以“write”开头,例如writeByte(),writeFloat()等。java.io.FilterOutputStream.PrintSt

大家好,又见面了,我是你们的朋友全栈君。

本文章为博主原创文章,未经授权,不得转载。

在java.io.FilterOutputStream.DataOutputStream:与机器无关地写入各种类型的数据以及String对象的二进制形式,从高位开始写。这样一来,任何机器上任何DataInputStream都能够读取它们。所有方法都以“write”开头,例如writeByte(),writeFloat()等。 

java.io.FilterOutputStream.PrintStream最初的目的是为了以可视化格式打印所有的基本数据类型以及String对象。这和DataOutputStream不同,它目的是将数据元素置入“流”中,使DataInputStream能够可移植地重构它们。

对于如何把一串字符串写成二进制,我一直迷惑不解,直到我看到下面的信息:

字符串的本质是char的序列,也就是char [ ]。因此,遍历写入每一个char,就完成了写一个字符串的功能!

那么问题又来了,如何把char写成二进制呢?

英语字母有ASCII码,可以把每个字符转换成对应的数字,那么汉字呢,日语呢,韩语呢,泰国语呢????????????????????????????????????????????????????

把心放肚子里吧,这个问题前人早就已经解决了。世界上的绝大部分字符都有一张类似于ASCII码表的字符和编码间的映射,那就是Unicode码表。看:

Unicode 字符编码标准是固定长度的字符编码方案,它包含了世界上几乎所有现用语言的字符。有关 Unicode 的信息可在最新版本的 The Unicode Standard 一书中找到,并可从 Unicode 协会 Web 站点(www.unicode.org)中找到。 Unicode 根据要编码的数据类型使用两种编码格式:8 位和 16 位。缺省编码格式是 16 位,即每个字符是 16 位(两个字节)宽,并且通常显示为 U+hhhh,其中 hhhh 是字符的十六进制代码点。虽然生成的 65000 多个代码元素足以用于 编码世界上主要语言的大多数字符,但 Unicode 标准还提供了一种扩展机制,允许编码一百多万个字符。扩展机制使用一对高位和低位代用字符来对扩展字符或补充字符进行编码。第一个(或高位)代用字符具有 U+D800 和 U+DBFF 之间的代码值,而第二个(或低位)代用字符具有 U+DC00 和 U+DFFF 之间的代码值。

unicode码真的可以用2个字节表示世界上的绝大部分字符。

至此,当看到一个char时,我仿佛看到了它背后隐隐欲现的0-65535间的数字,当看到一个String时,我仿佛看到了一串数字!

所以,DataOutputStream.writeChars(str)的源码也就明晰了

public final void writeChars(String s) throws IOException {
        int len = s.length();
      
        for (int i = 0 ; i < len ; i++) {
            int v = s.charAt(i);
            out.write((v >>> 8) & 0xFF); 
            out.write((v >>> 0) & 0xFF); 
        }
        incCount(len * 2);
    }

所以除了要遍历一遍string之外,其他的操作Yu DataOutputStream.writeShort(v)的源码没什么区别

public final void writeShort(int v) throws IOException {
        out.write((v >>> 8) & 0xFF);
        out.write((v >>> 0) & 0xFF);
        incCount(2);
    }

至此,就把一串字符串写成二进制了。

但是,你有没有一个疑问????????为什么(v >>> 8) & 0xFF ??为什么(v >>> 0) & 0xFF????不知道你有没有,反正我有。

具体疑问:1 为什么要用无符号的右移? 2 &0xFF不会使数的大小改变,为什么还要 &0xFF?

先科普一下:

0(零)xFF是16进制的255,也就是二进制的 1111,1111

& AND 按位与操作,同时为1时才是1,否则为0.

————位移运算计算机中存的都是数的补码,所以位移运算都是对补码而言的————

<< 左移 右补0

>> 有符号右移 左补符号位,即:如果符号位是1 就左补1,如果符号位是0 就左补0

>>>无符号右移 ,顾名思义,统一左补0

————————————————————————————————————————

要想知道为什么?我们应该想想,我们的目的是干什么的?开始已经讲了:先取高8位写入,再写入低8位.。

0000,0000,0000,0011     3的二进制原码,假设要写入的short字符对应的unicode码是3。

0000,0000,0000,0000      这是”>>>8″的结果                        

                  1111,1111       然后再 &0XFF                                                                         

                 0000,0000       最终结果                                                                                    

   这就得到了 3的原码0000,0000,0000,0011 的高8位。

    0000,0000,0000,0011        >>>0还是源码本身不变

                       1111,1111        &0XFF                                                                       

                      0000,0011        最终结果
这就得到了 3的原码0000,0000,0000,0011 的低8位。

其实,用有符号的右移>>也一样得到高/低8位,因为右移操作不改变数本身,返回一个新值,就像String。所以 “&0xFF” 就像计算机中的一把剪刀,当‘&’操作符两边数的bit位数相同时不改变数的大小,只是专门截出一个字节的长度。同理,&0x0F呢?得到4bits

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150768.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • navicat 15 linux 在线激活码【注册码】

    navicat 15 linux 在线激活码【注册码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • python中的subprocess_python函数与方法的详细

    python中的subprocess_python函数与方法的详细python3的subprocess的各个方法的区别(-)

  • JSON字符串转为java对象

    JSON字符串转为java对象在日常的java开发中,我们经常会需要接收到其它地方传过来的数据,格式也很多都是通过JSON格式来传递的。所以我们经常需要将JSON格式的数据转换为我们所需要的数据格式,比如javabean形式。对于只有一层的JSON格式的数据转换还是比较简单的。代码如下:Stringparam="{‘leader’:’headtearch’}";JSONObjectjsonObject…

  • DENSENET_rennet

    DENSENET_rennet1.首先对深度学习做一个简单的回顾2.介绍DenseNet1.1DNN回顾如下图所示是一个基本DNN结构,通过forward传播和backword传播来训练一个模型包含input层,L个隐藏层和一个output隐层使用的sigmoid激活函数一般的优化方法有如下几种GD:对所有样本计算完一次梯度然后更新权重SGD:每个样本计算一次梯度就更新权重

  • Zuul网关_zuul网关的作用

    Zuul网关_zuul网关的作用首先我们要知道为什么要使用网关呢?先复习一下之前说过的微服务的知识,最开始我们运行微服务就是三个重要部分1.服务端2.消费端3.注册中心首先用户在消费端发出消息,这个时候就需要负载均衡器Ribbon去调配服务,而且要使用到Hystrix去保护服务器,以免访问过多出现服务器过载,及时进行服务降级,然后我们通过消费端访问服务端的方法在最开始的时候使用的是RestTemplate去访问,当时是直接调配这个方法去访问,现在改进了一下,有Feign的出现,把Ribbon,Hystrix,还有RestTemp

  • oracle number整数,Oracle number类型的语法和用法

    oracle number整数,Oracle number类型的语法和用法Oraclenumber类型的语法很简单,就是:number(p,s)p,s都是可选的,假如都不填,p默认为38,s默认为-48~127。1.精度(precision),或总位数。默认情况下,精度为38位,取值范围是1~38之间。也可以用字符*表示38。2.小数位置(scale),或小数点右边的位数。小数位数的合法值为-48~127,其默认值取决于是否指定了精度。如果没有知道精度,小数位数则默…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号