Java基本數(shù)據(jù)類型(為什么byte最小值是-128,float二進(jìn)制轉(zhuǎn)化過程)

一、基本數(shù)據(jù)類型

image-20200721002249505

二、基本描述

bit --位:位是計算機中存儲數(shù)據(jù)的最小單位,指二進(jìn)制數(shù)中的一個位數(shù),其值為“0”或“1”。
byte --字節(jié):**字節(jié)是計算機存儲容量的基本單位,一個字節(jié)由8位二進(jìn)制數(shù)組成

一個byte的表現(xiàn)形式:

1000 0011

由8位0或1二進(jìn)制碼組成

其中第一位符號位表示正負(fù)數(shù),所以1000 0010 = 0* 2^0 + 1* 2^1 = -3

image-20200722220821760

所以byte的最大值:0111 1111 ;因為111 1111再進(jìn)1位1000 0000=2^7,所以111 1111為2^7-1 = 127

為什么byte的最小值是-128

正整數(shù)表示:

0000 0001 - 0111 1111 ====》1-127

負(fù)整數(shù):

1000 0001 - 1111 1111 ====》-1-(-127)

零:

0000 0000

那還有一個數(shù):

1000 0000 ===》 -0表示啥呢?

-127 - 127的范圍表示了255個數(shù),但是八位二進(jìn)制數(shù)由256種可能。

即2的8次方

我們先來看二進(jìn)制數(shù)的計算:

img

2+1 = [0000_0010]原+[0000_0001]原=[0000_0011]原 = 3

1+-1=[0000_00001]原+[1000_0001]原=[1000_0010]原=-2

顯然計算的時候出現(xiàn)了問題,為什么?

補碼的來源

從上面的原碼表中可以看見左邊每增加一個二進(jìn)制單位對應(yīng)的真數(shù)是遞減的,而右邊每增加一個二進(jìn)制單位對應(yīng)的真數(shù)是遞增的,所以對于原碼來說,能滿足正數(shù)的加法,但無法滿足負(fù)數(shù)的加法

為了滿足負(fù)數(shù)對加法的需求,就必須讓負(fù)數(shù)與他對應(yīng)的二進(jìn)制碼是同步遞增或者同步遞減

眾所周知,減去一個數(shù)相當(dāng)于加上這個數(shù)的相反數(shù),這樣減法就轉(zhuǎn)換成了加法。

于是就通過符號位不變,其余位取反來滿足這個同步遞增或者遞減的要求,由于正數(shù)本來就滿足它本身的加法,所以不需要做任何改變。這就是反碼的定義由來。

img

從上圖的反碼表中可以看到在運算不跨過0的時候,正負(fù)數(shù)的加法已經(jīng)能滿足要求

-2+1=[1111_1101]反+[0000_0001]反=[1111_1110]反=-1

127+1=[1000_0000]反=-127=128 加法算出來是128,由于128超過最大值,余1,所以取最小值開始的第一位,也就是

最小值-127,但是這里有個不合理的地方,就是[1111_1111]和[0000_0000]都表示0,這導(dǎo)致在實際計算中每當(dāng)跨過0一次,就有一個單位的誤差

-1+2=[1111_1110]反+[0000_0010]反=[0000_0000]反=0

要解決這個問題就必須讓反碼中的[1111_1111]和[0000_0000]合并,由于[1111_1111]+[0000_0001]=[0000_0000],所以在負(fù)數(shù)反碼的基礎(chǔ)上+1就可以解決反碼中跨0的誤差問題,同時不會對負(fù)數(shù)與它對應(yīng)的二進(jìn)制反碼的同步遞增產(chǎn)生影響,所以在反碼的基礎(chǔ)上+1就完美的解決了符號參與預(yù)算的問題,這就是補碼為什么是在負(fù)數(shù)反碼的基礎(chǔ)上+1的由來。


img

回到原來的問題0000 0000 - 1111 1111表示了在-127 - 127的范圍,那么1000 0000 就可以用來表示-128

[-128~127] 剛好256個數(shù)值,即2的8次方。

其他類型的表示范圍也是以此類推。

在Java中整型、實型、字符型被視為簡單數(shù)據(jù)類型,這些類型由低級到高級分別為:

(byte,short,char)--int--long--float--double

整數(shù)比浮點數(shù)低級。低級到高級可以自動轉(zhuǎn)換。而高級到低級需要用代碼強制轉(zhuǎn)換,不強轉(zhuǎn)會編譯錯誤。

三、Char字符型

1.JAVA中,char占2字節(jié),16位。可在存放漢字

2.char賦值

char a='a'; //任意單個字符,加單引號。

char a='中';//任意單個中文字,加單引號。

char a=111;//整數(shù)。0~65535。十進(jìn)制、八進(jìn)制、十六進(jìn)制均可。輸出字符編碼表中對應(yīng)的字符。

注:只能放單個字符

3、char運算

在JAVA中,對char類型字符可以與ASCII表對應(yīng)的數(shù)值來處理,可以做一些位運算

所以在遇到一些字符串查找字符等操作可以使用char對應(yīng)一個數(shù)值的特性來提高計算速度。

算法示例:

判定字符是否唯一

實現(xiàn)一個算法,確定一個字符串 s 的所有字符是否全都不同。

示例 1:

輸入: s = "leetcode"
輸出: false
示例 2:

輸入: s = "abc"
輸出: true
限制:

0 <= len(s) <= 100
如果你不使用額外的數(shù)據(jù)結(jié)構(gòu),會很加分。

思路
由于ASCII碼字符個數(shù)為128個,而且題目說了如果你不使用額外的數(shù)據(jù)結(jié)構(gòu),會很加分。因此可以使用兩個64位的long變量來存儲是否出現(xiàn)某個字符,二進(jìn)制位1表示出現(xiàn)過, 0表示未出現(xiàn)過。具體代碼如下:

    public boolean isUnique(String astr) {
        long low64 = 0;
        long high64 = 0;

        for (char c : astr.toCharArray()) {
            if (c >= 64) {
                long bitIndex = 1L << c - 64;
                if ((high64 & bitIndex) != 0) {
                    return false;
                }

                high64 |= bitIndex;
            } else {
                long bitIndex = 1L << c;
                if ((low64 & bitIndex) != 0) {
                    return false;
                }

                low64 |= bitIndex;
            }

        }

        return true;
    }

?
? 作者:yuruiyin
? 鏈接:https://leetcode-cn.com/problems/is-unique-lcci/solution/java-wei-yun-suan-by-npe_tle-2/
? 來源:力扣(LeetCode)
? 著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

首先利用char字符的對應(yīng)ASCII碼數(shù)值特性切入,該題目涉及位運算,后面再學(xué)習(xí)補充。

四、浮點型

基礎(chǔ): IEEE754是現(xiàn)在公認(rèn)的、最廣泛使用的浮點數(shù)轉(zhuǎn)換運算標(biāo)準(zhǔn),所以要知道浮點型在計算機的表示方式需要知道IEEE754標(biāo)準(zhǔn)

知識點一:IEEE754單精度(32位)的二進(jìn)制排列規(guī)則:符號位S(1位,0為正數(shù),1為負(fù)數(shù)) + 階碼E(8位) + 尾數(shù)M(23位)

知識點二:單精度的偏置常數(shù)為127(固定值),階碼 = 127 + 階

知識點三:計算公式

img

s為符號位,Exponent為指數(shù)位,Sig為尾數(shù)為部分

float單精度、32位(4個字節(jié))

img

### double雙精度、64 位(8個字節(jié))

img

### float單精度計算轉(zhuǎn)化過程

以float單精度計算轉(zhuǎn)化為例:

-22.75轉(zhuǎn)二進(jìn)制碼

float a = -22.75的二進(jìn)制碼式什么

1.轉(zhuǎn)換整數(shù)部分:

22 = 10110

2.轉(zhuǎn)換小數(shù)部分:
.75 = .5 + .25 = .11(二進(jìn)制)

3.把兩部分組裝起來,變成標(biāo)準(zhǔn)化:
10110.11 = 1.100112^4*

4.轉(zhuǎn)換指數(shù)部分:

階碼 = 127 + 階

127 + 4 = 1000 0011(二進(jìn)制)

5.結(jié)果
1 <u>1000 0011</u> <u>10011</u> 00 0000 0000 0000 0000(二進(jìn)制)

二進(jìn)制 1011 11101 110 0000 0000 0000 0000 0000轉(zhuǎn)化為float是多少?

1. s = 1

2.Exponent = 011 11101

011 11101 = 125

125 - 127 = -2

3.Significand

img
4.Repersents:-1.75(十進(jìn)制)2^(-2) = -0.4375*

float和double的一些總結(jié):

float:32位,數(shù)據(jù)范圍在3.4e-45~1.4e38,直接賦值時必須在數(shù)字后加上f或F

double:64位,數(shù)據(jù)范圍在4.9e-324~1.8e308,賦值時可以加d或D也可以不加

float、double兩種類型的最小值與Float.MIN_VALUE、 Double.MIN_VALUE的值并不相同,實際上Float.MIN_VALUE和Double.MIN_VALUE分別指的是 float和double類型所能表示的最小正數(shù)。也就是說存在這樣一種情況,0到±Float.MIN_VALUE之間的值float類型無法表示,0 到±Double.MIN_VALUE之間的值double類型無法表示。這并沒有什么好奇怪的,因為這些范圍內(nèi)的數(shù)值超出了它們的精度范圍。

Float和Double的最小值和最大值都是以科學(xué)記數(shù)法的形式輸出的,結(jié)尾的"E+數(shù)字"表示E之前的數(shù)字要乘以10的多少倍。比如3.14E3就是3.14×1000=3140,3.14E-3就是3.14/1000=0.00314。

五、引用類型

了解引用類型之前,可以先看一下Java運行時的內(nèi)存分配模型

image-20200721233515255

Java把內(nèi)存分成兩種,一種叫做棧內(nèi)存,一種叫做堆內(nèi)存

  • 在函數(shù)中定義的一些基本類型的變量和對象的引用變量都是在函數(shù)的棧內(nèi)存中分配。當(dāng)在一段代碼塊中定義一個變量時,java就在棧中為這個變量分配內(nèi)存空間,當(dāng)超過變量的作用域后,java會自動釋放掉為該變量分配的內(nèi)存空間,該內(nèi)存空間可以立刻被另作他用。
  • 堆內(nèi)存用于存放由new創(chuàng)建的對象和數(shù)組。在堆中分配的內(nèi)存,由java虛擬機自動垃圾回收器來管理。
  • 在堆中產(chǎn)生了一個數(shù)組或者對象后,還可以在棧中定義一個特殊的變量,這個變量的取值等于數(shù)組或者對象在堆內(nèi)存中的首地址,在棧中的這個特殊的變量就變成了數(shù)組或者對象的引用變量

堆內(nèi)存特點

  • 每一個 new 出來的東西都有地址值;
  • 每個變量都有默認(rèn)值 (byte, short, int, long 的默認(rèn)值為 0;float, double 的默認(rèn)值為 0.0;char 的默認(rèn)值為 “\u0000”;boolean 的默認(rèn)值為 false;引用類型為 null);
  • 使用完畢就變成垃圾,但是并沒有立即回收。會有垃圾回收器空閑的時候回收。

棧內(nèi)存特點

  • 局部變量:在方法的定義中或者在方法聲明上的變量稱為局部變量。
  • 特點:棧內(nèi)存的數(shù)據(jù)用完就釋放。

所以引用變量存在兩個屬性:

  • 引用變量本身的值,存儲在堆中
  • 引用變量的在堆內(nèi)存中的地址指針變量,存儲在棧中

引用的過程:

img
圖片來源 Java 中的內(nèi)存分配

用以下的代碼來看一下引用類型存儲模型與基本類型變量只存儲在棧的問題

package com.java.test;

public class MainTest {
    public static void main(String[] args) {
        Student s = new Student("小明",1);
        int  a = 10;
        System.out.println("學(xué)生的信息如下: "+s.toString());
        System.out.println("變量a的值="+a);
        change(s,a);
        System.out.println("調(diào)用方法后");
        System.out.println("學(xué)生的信息如下: "+s.toString());
        System.out.println("變量a的值="+a);

    }
    static void change(Student s, int a) {
        a=a-10;
        s.setAge(1);
        s.setName("大明");
    }


}

class Student{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

運行結(jié)果:

image-20200721235709306

Java 八大基本數(shù)據(jù)類型

關(guān)于IEEE754單精度(32位)的計算步驟(超詳細(xì))

關(guān)于計算機中補碼的問題

關(guān)于IEEE754單精度(32位)的計算步驟(超詳細(xì))

JAVA中的幾種基本數(shù)據(jù)類型是什么,各自占用多少字節(jié)

Java中的八種基本數(shù)據(jù)類型所占字節(jié)的求法

Java 中的內(nèi)存分配

計算機原碼,反碼,補碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內(nèi)容