计算机的世界:[-bit之魂-]
這里就是這樣的世界,這里的1 + 1 = 10 --二進制物語
儒仁慈世安家業,墨守規矩自方圓。 兵戈鐵馬平天下,法理束欲定千秋。 佛釋惡業普渡生,道化萬物共長存。 諸子百家何為首? 且問君心何所求。---- 張風捷特烈《求》 2019.2.15 復制代碼零、前言
關于數字化個人認為是計算機世界對現實世界的映射(或稱采樣或模擬)。
現實世界包括客觀存在和人類文明衍生物(自然科學和廣義文學)。
數字化就是將這些映射為二進制數據。本文觀點為個人體悟總結,僅供參考
本文包括
1.散扯引入一些概念和個人體悟 2.進制及其轉化的相關問題 3.邏輯運算 4.字符的編解碼 5.java中的基本數據類型 復制代碼一、先天八卦與烽火狼煙
先聲明我不是尊學崇術的人,百家于我如一。
道家認為萬物皆有陰陽,這跟計算機世界一切皆有0,1一樣。
| 生存空間 | 地球 | 計算機系統(手機、電腦及智能終端) |
| 資源 | 地球提供 | 計算機系統提供 |
| 食物 | 可消化的能量體 | 可處理的數據體 |
| 消化 | 原生食物-->可用能量 | 原生數據-->可用數據 |
| 廢物 | shi(化驗看健康狀況) | log (分析看健康狀況) |
| 行為 | 唱歌,做作業,看小說... | 播放音樂,放視屏,顯示小說... |
| 外觀 | 化妝,換發型,換衣服... | 美化UI,齊劉海?,換膚... |
| 收藏品 | 古董,金錢,武器... | 緩存文件cache |
| 誕生 | 父母 | Coder |
| 家族優勢 | 富二代?(金錢支持) | 大佬公司的新產品(技術支持) |
| 生態群 | 娛樂圈, 教育界,學生黨... | 播放相關,教育相關,游戲類... |
| 最廣闊存在 | 無限空間(宇宙) | 無限內存(不可描述) |
| 最底層表現形式 | 不可描述(元素/分子?) | 0 和 1 |
1、先天八卦 (-吹牛的絕佳資本-)
道有言:易生太極,太極生兩儀,兩儀生四象,四象生八卦 。
先天八卦還是蠻好玩的,至于洛書和河圖的九宮和后天八卦...
當把陰(斷橫)看做0,陽(連橫)看做 1,自下而上來表示
看過俠嵐的應該比較熟悉(我都忍不住說絕招了...)
在八卦之上再添加陰陽變化,就形成64卦,如果萬物都由陰陽生成
那么我們的世界也是二進制的變化?細思恐極...
這里并不是故弄玄虛,只是想說明一下二進制的變化力
2.烽火狼煙
小學的那道題印象深刻(具體數據當然記不清了):
一個城池邊防有六座烽火臺,通過狼煙來通知軍隊敵軍人數, 以二進制表示:點煙的代表1,沒點的代表0 ,化成十進制后的1000倍即是敵軍人數 下面敵軍來了多少人?110010 = 2^5+2^4+2^1=32+16+2=50 答:來了50000人 復制代碼這就有意思,來了50000人我總不能在天上寫個50000吧,
兩種狀態和六個變化點,再結合狀態獲取的途徑,烽火狼煙確實實現了信息的傳遞
但功勞是烽火狼煙嗎,是二進制嗎? 烽火狼煙只是途徑,而二進制只是規則。
說了那么多,想表達一點:變化可以附加信息
二、進制相關
1.我與二進制
小學看二進制,不是1就是0唄,我蒙一下還有一半概率! 中學看二進制,覺得有點意思,不是1就是0,誰想出來的,這么無聊! 高學看二進制,面無表情...二進制就二進制唄,管我甚事,反正我會算! 大學看二進制,不聽不聽,王八念經...! 現在看二進制,擦,哲學啊! 復制代碼2.狀態與變化點
一種機制的變化總和=狀態的變化點次方
道家: 狀態:陰陽 變化點:爻 如八卦是陰陽的三種變化,稱為三爻 , 兩儀即 二爻計算機: 狀態:0 , 1 (高電平1和低電平0) 變化點:位 如一個int是0,1的32種變化,稱為32位,boolean即 1位(真假)|--為什么狀態和變化這么重要? 拿烽火狼煙來說,能用十進制嗎? 答案:能 ! 只要規則定制完善即可,比如九種顏色的煙代表1~9,0代表不點 這樣就能形成10種狀態,也就是十進制,6座烽火臺可以表示0~999999中的任意一個 但是成本太高,可行性也很低;點與不點是兩種天然的狀態,干嘛非要瞎折騰 111111 最大表示 63(即2^6-1) 這和 999999(即10^6-1),兩者的信息量差距還是非常大的 復制代碼3.為什么計算機非要用二進制
天時-地利-人和
天時:電氣時代的來臨,人類掌握了電的使用,機械和電力結合的歷史洪流 地利:二進制的物理可實現(高低電平)、邏輯運算能力、結構與運算規則簡單 人和:人才輩出,各個學科都誕生出一批大師,學術氛圍...二進制加法:0+0=0 1+0=1 0+1=1 1+1=10 天然與 二進制乘法:0*0=0 1*0=0 0*1=0 1*1=1 天然或 復制代碼4、進制轉化
這里我提個問題,來想一下:
是不是所有的十進制實數都能轉化成二進制?
是不是所有的其他進制實數都能轉化成十進制?
4.1.其他進制轉化為10進制
一氣化三清,公式走起
R:基數(進制) i:數字的位置 權:R的i次方 n:整數位數-1 m:小數位數------------------345.6 十進制 ---------------------------3 4 5 6↓ ↓ ↓ ↓ 3*10^2 + 4*10^1 + 5*10^0 + 6*10^-1 300 + 40 + 5 + 0.6 = 345.6基數 R=10; n=2; m=1 對于3而言:i=2 權:10^2 K=3 對于4而言:i=1 權:10^1 K=4 對于5而言:i=0 權:10^1 K=5 對于5而言:i=-1 權:10^-1 K=6------------------345.6八進制轉10進制 ---------------------------3 4 5 6↓ ↓ ↓ ↓ 3*8^2 + 4*8^1 + 5*8^0 + 6*8^-1 192 + 32 + 5 + 0.75 = 229.75基數 R=8; n=2; m=1 對于3而言:i=2 權:8^2 K=3 對于4而言:i=1 權:8^1 K=4 對于5而言:i=0 權:8^1 K=5 對于5而言:i=-1 權:8^-1 K=6---------------11001.1二進制轉10進制 --------------------------1 1 0 0 1 1 ↓ ↓ ↓ ↓ ↓ ↓ 1*2^4 + 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0 + 1*2^-1 16 + 8 + 0 + 0 + 1 + 0.5 = 25.5基數 R=2; n=4; m=1 自左到右 對于1而言:i=4 權:2^4 K=1 對于1而言:i=3 權:2^3 K=1 對于0而言:i=2 權:2^2 K=0 對于0而言:i=1 權:2^1 K=0 對于1而言:i=0 權:2^1 K=1 對于1而言:i=-1 權:2^-1 K=1二進制--->十進制:權值相加 復制代碼4.2.十進制轉換成二進制
--------------十進制49轉換二進制----------------------- --------------------- 權值 49 / 2 = 24 ······1 2^0 = 1 24 / 2 = 12 ······0 --- 12 / 2 = 6 ······0 --- 6 / 2 = 3 ······0 --- 3 / 2 = 1 ······1 2^4 = 16 1 / 2 = 0 ······1 2^5 = 32 --倒取-->110001 :小學老師告訴我這樣轉化,到現在我也不明白why? 十進制整數可以和二進制整數一一對應,那小數呢?--------------十進制0.8125轉換二進制----------------------- ---------------------------- 權值 0.8125 * 2 = 1.625 1 2^-1=0.5 0.625 * 2 = 1.25 1 2^-2=0.25 0.25 * 2 = 0.5 0 --- 0.5 * 2 = 1 1 2^-4=0.0625 0 * 2 = 0 0 --- over 0.5+0.25+0.0625 = 0.8125 ---準確無誤,這老師可沒教過--------------十進制0.6531轉換二進制----------------------- ---------------------------- 權值 0.6531 * 2 = 1.3062 1 2^-1=0.5 0.3062 * 2 = 0.6124 0 --- 0.6124 * 2 = 1.2248 1 2^-3=0.125 0.2248 * 2 = 0.4496 0 --- 0.4496 * 2 = 0.8992 0 --- 0.8992 * 2 = 1.7984 1 2^-6=0.03125 .... 無窮盡 0.5+0.125+0.03125 = 0.65625 ≈ 0.6531 這就更玄乎了...竟然無窮盡,所以這便是計算機中小數的瑕疵 復制代碼4.3.二進制與八進制十六進制間的轉化
小數對二進制來說是個無法磨滅的瑕疵,也許有什么二進制的無限不循環(循環)小數也說不定
我認為數是美的,瑕疵只是我們還無法忍識的另一種美的存在形式,2,8,16完美轉化
四、計算機中數的表示
1.無符號
結合烽火狼煙,相當于有八個烽火臺,每個烽火臺有2個狀態(0,1)
能夠表示 0~ 2^8-1 個正整數
2.加入符號
對于整數而言要有符號,java中的byte是帶有符號(+或-)的,于是要扣除一位
就像烽火狼煙無法表示友方來軍多少人,可以扣除一個作為友方來軍體還是敵方來軍
所以就7個烽火臺有數字價值,好處是效用增加,壞處是表示的數范圍減小
能夠表示-2^7 ~ 2^7-1 即(-128 ~ 127)個正整數
3.減法: byte 為例
計算機無法直接做減法,但是加法也可以變成減法
今天剛好發生了一件事來表述:
4.小數的表示:float為例
7.25(十進制) = 111.01(二進制 ) 111.01(二進制)=1.1101*2^2(二進制) 類比科學計數法符號位:0 階碼:2 + 127 ---二進制---> 10000001 尾數:1101|---在java中可用以下代碼驗證:記得補滿32位 float a = 7.25f; int b=Float.floatToIntBits(a); String string = Integer.toBinaryString(b); System.out.println(string); //0100 0000 1110 1000 0000 0000 0000 0000 復制代碼四、邏輯控制
1、四個位運算符
隨便寫了幾個值,眼都瞅花了...
位與:& 兩個都是1為1 位或:| 只要有1就是1 位非:~ 全取反 位異或:^ 兩個都不一樣為1例子:c = a & b 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705& 0000 0000 0000 0000 0100 0100 1011 0101 [b] 0x000044b5 17589 --------------------------- 0000 0000 0000 0000 0000 0100 1010 0001 [c] 0x000004a1 1185例子:d = a | b0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705| 0000 0000 0000 0000 0100 0100 1011 0101 [b] 0x000044b5 17589 ---------------------------0000 0000 0000 0000 0100 0110 1011 1101 [d] 0x000046bd 18109例子:e = ~a 0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705~ 1111 1111 1111 1111 1111 1001 0101 0110 [e] 0xfffff956 -1706例子:f = a ^ b0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705^ 0000 0000 0000 0000 0100 0100 1011 0101 [b] 0x000044b5 17589 ---------------------------0000 0000 0000 0000 0100 0010 0001 1100 [f] 0x0000421c 16924 復制代碼2.java中校驗上面位運算的例子
public static void main(String[] args) {int a = 0x000006a9;//0000 0000 0000 0000 0000 0110 1010 1001int b = 0x000044b5;//0000 0000 0000 0000 0100 0100 1011 0101int c = 0x000004a1;//0000 0000 0000 0000 0000 0100 1010 0001int d = 0x000046bd;//0000 0000 0000 0000 0100 0110 1011 1101int e = 0xfffff956;//1111 1111 1111 1111 1111 1001 0101 0110int f = 0x0000421c;//1111 1111 1111 1111 1111 1001 0101 0110System.out.println(a);//1705System.out.println(b);//17589//位與System.out.println(a & b);//1185System.out.println(c);//1185//位或System.out.println(a | b);//18109System.out.println(d);//18109//位非System.out.println(e);//-1706System.out.println(~a);//-1706//位異或System.out.println(f);//-1706System.out.println(a ^ b);//-1706 } 復制代碼3.移位操作
左移n位相當于乘以2的n次方 a<<n
右移n位:a>>n
4.需要注意的幾種套路:
1.將兩個int值得低八位(最后一個字節)拼成一個short取低8位: int 值 & 0x000000FF ----看一下挺好理解的0000 0000 0000 0000 0000 0110 1010 1001 [a] 0x000006a9 1705 & 0000 0000 0000 0000 0000 0000 1111 1111 -------------------------------------------------0000 0000 0000 0000 0000 0000 1010 1001 [i] 0x000000a9取低8位后左移8位: int 值 & 0x000000FF0000 0000 0000 0000 0100 0100 1011 0101 [b] 0x000044b5 17589 & 0000 0000 0000 0000 0000 0000 1111 1111 -------------------------------------------------0000 0000 0000 0000 0000 0000 1011 0101 [j] 0x000000b50000 0000 0000 0000 1011 0101 0000 0000 [j] 左移8位 0x0000b5000000 0000 0000 0000 0000 0000 1010 1001 [i] 0x000000a9+ 0000 0000 0000 0000 1011 0101 0000 0000 [j] 0x0000b500-------------------------------------------------0000 0000 0000 0000 1011 0101 1010 1001 0x0000b5a9強轉成short完成任務:1011 0101 1010 1001 2.當 n = 2^i 時,x % n = (n - 1) & x (這是看HashMap源碼學到的),例如: 至于原理沒研究過,但位運算要比%運算要快,所以后者有優勢,HashMap里便是后者 int x = 67444; int i1 = 255 & x;//===>67444 % 255 int i2 = x % 256;//===>67444 % 256 System.out.println(i1);//166 System.out.println(i2);//166 復制代碼五、字符編碼
你有沒有想過這樣一個問題?
計算機文件存儲的基礎是字節,為什么一個字節(byte)是8位
1.ASCII碼
這是我能找到最清楚的ASCII碼表了,以后有時間自己畫一幅(已加入TODO事項)
ASCII碼中字符和控制字符一共有128種,即2^7,用7個二進制便可以映射
類比烽火狼煙,由變化映射出數字。這里映射出字符,理念是一致的,即用變化承載信息
標準ASCII碼使用了七位,但會預留一位作為校驗位
IBM對ASCII碼進行了擴充,攻256個字符,屬于擴展ASCII碼(非標準)
2.漢字(及其他語言字符)的編碼
符號型的文字,如漢字、日文、韓文這就復雜了:一多,二雜,三歧義
7個字節128個空間肯定不夠用,那就增加變化唄,再來8個字節
Unicode使用兩個字節即16位來映射字符,一共2^16種,即65 536
然后發現還是不怎么夠用,再擴充? 然后UTF-32
這下肯定夠了容量 4 294 967 296 個,但是也太浪費了吧!
我要裝個a,用128的籃字就行了,你給我個能裝42億的籃子?受寵若驚...
于是UTF-8閃亮登場
ASCII 碼表:美國標準信息交換碼 1字節--使用:7位 ISO8859-1:拉丁碼表。歐洲碼表 1字節--使用:8位 GB2312:中國的中文編碼表。 2字節--使用:16位 GBK:GB2312升級版,增加中文 2字節--使用:16位 Unicode:國際標準碼 2字節--使用:16位 UTF-8:Unicode升級版 能用1個字符表示用1個字符,不然用2個,要還是不夠用,使用3個字節 復制代碼3.指定編碼表寫出文件
public class 編碼表測試 {public static void main(String[] args) throws IOException {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("UTF-8.txt"),"utf-8");OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("GBK.txt"),"gbk");osw.write("張風toly");osw.close();} } 復制代碼4.計算機怎么識別張字的
將張這個字符串用utf-8編碼轉化為字節數組,可看到是[-27, -68, -96]三個數
這三個數又代表什么?
用計算器查看十進制數的字節型的二進制,可以看到:
5.使用不同碼表讀取測試
InputStreamReader isr_GBK_gbk = new InputStreamReader(new FileInputStream("GBK.txt"),"gbk"); char[] buf = new char[10]; int len = isr_GBK_gbk.read(buf); System.out.println(new String(buf, 0, len));//張風tolyInputStreamReader isr_GBK_utf8 = new InputStreamReader(new FileInputStream("GBK.txt"),"utf-8"); char[] buf2 = new char[10]; int len2 = isr_GBK_utf8.read(buf2); System.out.println(new String(buf2, 0, len2));//�?�tolyInputStreamReader isr_UTF8_utf8 = new InputStreamReader(new FileInputStream("UTF-8.txt"),"utf-8"); char[] buf4 = new char[10]; int len4 = isr_UTF8_utf8.read(buf4); System.out.println(new String(buf4, 0, len4));//張風tolyInputStreamReader isr_UTF8_gbk = new InputStreamReader(new FileInputStream("UTF-8.txt"),"gbk"); char[] buf3 = new char[10]; int len3 = isr_UTF8_gbk.read(buf3); System.out.println(new String(buf3, 0, len3));//寮犻toly 復制代碼6.位bit與字節byte
位是計算機的基石,字節是文件的基石
如果說位是0,1的陰陽變化?, 字節便是256卦象,而這256卦象便是文件的最小單元
256卦象是多少爻呢 ? 8 ,也就是 8 個位來記錄這256種變化
所有文件都是以字節為單位的,你見過哪里有10000.5字節嗎?
7.形象體感一下字節的存在
就拿我頭像來看看吧,1,153,744 字節 115萬多字節?! 也就是920萬多位
也就是說要近一億個烽火臺才能表達出這張圖片的信息?
六、再來看java的幾種數據類型
1.八仙一覽
經過上面走一遭,是不是感覺更熟悉了?
boolean 布爾類型 1字節 byte 字節 1字節、有符號 char 字符型 2個字節、無符號、Unicode字符兼整數 short 短整型 2個字節、有符號、整數 int 整型 4個字節、有符號、整數 long 長整型 8個字節、有符號、整數 float 浮點型 4個字節、有符號、小數 符號位:1bit,階碼:8bit, 尾數:23bit double 雙精度浮點 8個字節、有符號、小數 符號位:1bit,階碼:11bit,尾數:52bit 復制代碼2.拋張表
| boolean | 1 | 8 | true/false | false |
| byte | 1 | 8 | -2^7 ~ 2^7-1 (-128 ~ 127) | 0 |
| char | 2 | 16 | 0 ~ 2^16-1(0 ~ 65535) | null |
| short | 2 | 16 | -2^15 ~ 2^15-1 (-32768~32717) | 0 |
| int | 4 | 32 | -2^31 ~ 2^31-1 (-2147483648~2147483647) | 0 |
| long | 8 | 64 | -2^63 ~ 2^63-1 | 0L |
| float | 4 | 32 | ±1.4E-45 ~ ±3.4028235E38 | 0.0f |
| double | 8 | 64 | ±4.9E-324 ~ ±1.7976931348623157E308 | 0.0d |
3.上面給出的是用JAVA的API獲取的
難道就沒有人疑問,float的最小值? 我看到有點蒙,Are you sure?
|---我不淡定了 測試一下 float f = -1.5f; System.out.println(Float.MIN_VALUE > f);//true|---Float獲取最小值可能比一個float大?---->[Float.java]------------------# 看來是直接定義的常量 這就有意了---代碼注釋是最小非零整數public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f|---所以嚴格說取值范圍應該加上±號,否則不嚴謹,網上基本上都是正的 復制代碼4.咱就是喜歡校驗的人
畢竟實踐是檢驗真理的唯一標準
float f = 0.0 00000 00000 00000 00000 00000 00000 00000 00000 00001f;//Error 果然第46個0的時候報錯了,double就沒事double d = 0.000000000000000000000000000000000000000000000000000000000000000000000000000001; 復制代碼好了,本篇沒人挺多的,如果你認真看完,一定受益頗多
而我作為作者,受益就更加豐富了,總結一下,有些東西算是理清了
后記:捷文規范
1.本文成長記錄及勘誤表
| V0.1-- | 2018-2-15 | 無 |
發布名:計算機的世界:[-bit之魂-]
捷文鏈接:www.jianshu.com/p/ee74ea725…
2.更多關于我
| 張風捷特烈 | 1981462002 | zdl1994328 |
我的github:github.com/toly1994328
我的簡書:www.jianshu.com/u/e4e52c116…
我的掘金:juejin.im/user/5b42c0…
個人網站:www.toly1994.com
3.聲明
1----本文由張風捷特烈原創,轉載請注明
2----歡迎廣大編程愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這里,我在此感謝你的喜歡與支持
總結
以上是生活随笔為你收集整理的计算机的世界:[-bit之魂-]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简单的jvm调优
- 下一篇: 新Astaroth***病毒可利用杀毒软