日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 无符号 类型_java中符号类型和无符号类型的问题分析

發布時間:2025/3/20 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 无符号 类型_java中符号类型和无符号类型的问题分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一 參考博文

二 java中的無符號數和有符號數

在計算機中,可以區分正負的類型,稱為有符號類型,無正負的類型,稱為無符號類型。

使用二進制中的最高位表示正負

計算機中用補碼表示數值;另外,用二進制的最高位表示符號,0表示正數、1表示負數。

無符號和有符號數的范圍的區別

無符號數中,所有的位都用于直接表示該值的大小;有符號數中最高位用于表示正負,所以,正值時,該數的最大值就會變小:

無符號數:1111 1111 值:255

有符號數:0111 1111 值:127

同樣一個字節,無符號的最大值是255,有符號的最大值是127

三 java中的基本類型

Java的原始類型里除了char是無符號類型之外,其他都是有符號數據類型,如果需要某個寬度的無符號類型,可以用>>>進行轉化,這個是java的無符號右移操作符,或者使用下一個寬度的帶符號類型來模擬,

例如,需無符號的short,就用int來模擬:

int toUnsigned(short s) {

return s & 0x0FFFF;

}

java中十進制的字面常理只有一個特性,就是所有的十進制字面常量都是正數,如果想寫一個負的十進制,則需要在正的十進制字面常量前面加上“-”就好了。

但是十六進制或者八進制的字面常量就不一定是正數或者負數,如果最高位是1,那么就是負數:

System.out.println(0x80);//128

//0x81看作是int型,最高位(第32位)為0,所以是正數

System.out.println(0x81);//129

System.out.println(0x8001);//32769

System.out.println(0x70000001);//1879048193

//字面量0x80000001為int型,最高位(第32位)為1,所以是負數

System.out.println(0x80000001);//-2147483647

//字面量0x80000001L強制轉為long型,最高位(第64位)為0,所以是正數

System.out.println(0x80000001L);//2147483649

四 補碼與真值

這里先看一個問題:

@Test

public void test01(){

System.out.println(0x80000000); // -2147483648

}

這個結果是怎么得來的?

要搞明白這個問題,得先明白幾個概念:

機器數:

一個數在計算機中的二進制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號, 正數為0, 負數為1.

比如,十進制中的數 3 ,計算機字長為8位,轉換成二進制就是00000011。如果是 -3 ,就是 10000011 。那么,這里的 00000011 和 10000011 就是機器數

真值:

因為第一位是符號位,所以機器數的形式值就不等于真正的數值。例如上面的有符號數 10000011,其最高位1代表負,其真正數值是 -3 而不是形式值131(10000011轉換成十進制等于131)。

所以,為區別起見,將帶符號位的機器數對應的真正數值稱為機器數的真值(即補碼表示的值)。

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

計算真值

就拿-3來說,機器數為 10000011,那么補碼是 11111101,所以真值就是補碼的值:

補碼求值公式:補碼的最高位有效位乘以(-1),然后按一般求二進制的方法求值

例如:

-3的補碼 11111101 = (-1)12^7 + 12^6+.... 12^0 = -3

3的補碼 00000011 = (-1)027+........1*20= 3

0x80000000問題解析

再來看0x80000000為什么等于-2147483648,Java中用此十六進制表示int的最小值:

/**

* A constant holding the minimum value an {@code int} can

* have, -231.

*/

@Native public static final int MIN_VALUE = 0x80000000;

此十六進制數內存中存儲的的確是0x80000001的二進制碼。因為使用十六進制給int賦值時,這里的十六進制是補碼形式。

也就是說,我們給變量賦的是補碼,不是源碼,所以會直接把0x80000001這個補碼存入內存

補碼求值得: 0x80000000 = (-1)1231+.....+0*20 = -2147483648

所以這個值是這樣來的!

五 java中的數據類型符號擴展

先看一個jdk源碼中int轉為long用到的方法:

@Test

public void test03(){

final long l = -5 & 0xffffffffL;

System.out.println(l); // 4294967291

}

如果運算一個操作數是long型,而另一個操作數是int類型。為了執行該計算,Java將int類型的數值用拓寬原生類型轉換提升為long類型,然后對兩個long類型數值相加。

因為int是有符號的整數類型,所以這個轉換執行的是符號擴展。

-5 轉換為long再轉換為二進制,0xffffffff轉換為二進制

進行與運算:

1111111111111111111111111111111111111111111111111111111110000101

0000000000000000000000000000000011111111111111111111111111111111

---------------------------------------------------------------------- & 與運算,兩個都為1才為1,否則為0

0000000000000000000000000000000011111111111111111111111110000101= 4294967173 (十進制)

為什么-5轉long前面要補1呢,這里就需要知道符號擴展規則:

窄的整型轉換成較寬(字節數多)的整型時符號擴展規則:

如果最初的數值類型是有符號的,那么就執行符號擴展(即如果符號位為1,則擴展為1,如果為零,則擴展為0);

如果它是char,那么不管它將要被提升成什么類型,都執行零擴展,

如果將一個char數值c轉型為一個寬度更寬的整型,并且希望有符號擴展,那么就先將char轉型為一個short,它與char上個具有同樣的寬度,但是它是有符號的

寬的整型轉換成窄的整型直接截取低位的值,高位扔掉

所以上面-5符號是1,所以進行符號擴展前面都補1,補成long(64位),再進行位運算得出結果!

六 Java中byte轉換int時與0xff進行與運算的原因

jdk源碼中byte轉int用到了 & 0xff,比如String的API:

public static char charAt(byte[] value, int index) {

if (index < 0 || index >= value.length) {

throw new StringIndexOutOfBoundsException(index);

}

return (char)(value[index] & 0xff);// 先轉int,再轉char

}

這里為什么要用與運算呢? 因為char是無符號類型,所以不能進行符號擴展,需要零擴展,即前面補0

窄整型->寬整型要進行符號擴展,這里byte->cahr是窄到寬,如果不想進行符號擴展,則需要&0xff處理,先轉int消除掉符號擴展,再轉char即可

(b & 0xff)的結果是32位的int類型,前24被強制置0,后8位保持不變,然后轉換成char型時,直接截取后16位。這樣不管b是正數還是負數,轉換成char時,都相當于是在左邊補上8個0,即進行零擴展而不是符號擴展

至于為什么要進行零擴展: 因為char是無符號類型,他會把 1111 1111 當做65535而不是-1,,所以你前面補1的話數就會變很大,所以這里需要進行0擴展,于是 & 0xff這種騷操作就來了,這里確實有點繞!如果不看源碼(并且要認真看啊,哈哈)一般發現不了這種問題

再比如下面代碼:

@Test

public void test01(){

byte b=-1;

System.out.println((int)b); // -1

System.out.println(b & 0xff); // 255

}

這里第二行255應該都好說,高位清零就是,至于直接強轉為-1,那么符號擴展之后補碼為11111111111111111111111111111111,求出結果原碼:100000000000000000000000000001 還是-1,所以就是上面的結果,原理就是這樣!

主要就是一個符號擴展延伸出來的問題!

總結

以上是生活随笔為你收集整理的java 无符号 类型_java中符号类型和无符号类型的问题分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品一区二区av | 小泽玛丽亚在线观看 | 亚洲九九 | 日韩欧美国产高清91 | 解开乳罩喂领导吃奶 | 大奶在线播放 | 精品美女www爽爽爽视频 | 重口变态虐黄网站 | 午夜精品免费视频 | 青青草55| 综合人人| 国产精品香蕉在线 | 亚洲国产精品网站 | 天天干天天操av | 9191在线视频 | 欧美精品久久天天躁 | 成年人在线免费 | 日美女网站 | 欧美精品一卡二卡 | av在线网址观看 | 日韩国产欧美精品 | 国产成人av在线 | 欧美黑吊大战白妞 | 变态另类一区 | 伊人久久精品一区二区三区 | 特黄老太婆aa毛毛片 | 色综合色综合 | 柠檬av导航 | 久久中文免费视频 | 91免费在线视频 | 伊人365影院 | 日本免费一区二区三区四区五六区 | 国产欧美久久久 | 国产午夜精品一区二区三区欧美 | 亚洲乱亚洲 | 国产999 | 免费一级片在线观看 | 亚洲免费国产视频 | 日韩两性视频 | 国产天堂av在线 | 一级在线| 亚洲国产精品成人综合久久久 | 色综合久久久久 | 男人天堂aaa | 亚洲高清在线观看视频 | av片网址 | 成人精品免费网站 | 青青色在线 | 乌克兰毛片 | 精品欧美视频 | 成人a级免费视频 | 成人欧美一区二区 | 被灌满精子的波多野结衣 | 99久精品视频| 日韩久草 | 大桥未久av一区二区三区中文 | 九九一级片| 九九久久精品视频 | 国模私拍在线 | 激情综合丁香五月 | 国产精品国产三级国产专播精品人 | 亚洲成人久 | 中文字幕一区二区三区波野结 | 天堂综合网久久 | 亚洲精品日韩在线观看 | 成人免费黄色片 | 99天堂网 | 成人亚洲网 | 国产一区二区伦理 | 婷婷欧美 | xxxwww国产| 五十路毛片 | 国产三级三级在线观看 | 农村搞破鞋视频大全 | 葵司免费一区二区三区四区五区 | 日韩污视频在线观看 | 97人妻精品一区二区三区软件 | 一区二区福利 | 日韩免费观看一区二区三区 | 久久一区二区三区精品 | 色综合久久av | 西西久久 | 葵司免费一区二区三区四区五区 | 一级黄色大片免费观看 | 国产精品一二三四区 | 朋友人妻少妇精品系列 | 91在线视频观看 | 蜜桃av免费在线观看 | 久久人人爽天天玩人人妻精品 | 男男黄网站 | 狠狠操一区二区 | 韩国一区二区在线播放 | 一区二区三区在线观看av | 91久久精品国产91久久 | 久久久久成人精品免费播放动漫 | 免费网站观看www在线观看 | 日韩一区在线免费观看 | 免费高清成人 | 天堂俺去俺来也www 欧美大片在线播放 |