二進位小總結

2021-01-11 紙鶴視界

真值與機器值

真值很好理解,就是十進位的數字前面再加上正負號,這是人類可以簡單識別的數字,比如 0、±16、±1084、±10.34、±100.453 等,而正數前面的+符號可以省略。機器值從字面理解就是機器(計算機)識別的值,實際上也確實是這個意思。

計算機中通過高低電平表示1或者0,這樣就可以表示一個二進位的數值。一個1或者0表示的數值位稱為一個bit,而計算機中存儲和傳輸數據的最小單位是一個字節(byte)也就是8個bit,所以說計算機所有計算本質上都是基於二進位。

在計算機中,我們可以使用1個或者多個字節存儲一個數,但無論是多少個字節,其大小肯定是固定的,同時其所能表示的數值的範圍也是固定的。比如說對使用1個字節存儲的數進行計算或者傳輸,那麼這個數所能表示的最小值為00000000最大值為11111111,轉換為十進位為0 ~ 255。那麼無論對這個數做了什麼計算,無論計算之後的結果為多少都不能超出這個範圍,同理使用2個字節存儲的數範圍為0 ~ 65535。

由於很多時候一個數據需要使用2個或者2個以上的字節表示,那麼這種數據無論是存儲還是傳輸的時候都會有一個順序的問題,也就是大小端對齊(字節序)問題。在存儲時高位字節在前為大端對齊,反之為小端對齊。在數據傳輸時先傳輸高位字節為大端字節序,反之為小端字節序。目前絕大多數平臺內部都是小端對齊的方式存儲數據,而大多數通信協議卻都是用大端字節序傳輸數據,所以這一點值得注意一下。

符號位與數值位

計算機中使用二進位存儲傳輸和計算數值,但是不能只有數值,計算的時候還得有正負之分。在計算機中使用最高bit位的數值來表示正負號,這個bit位稱作符號位。

計算機中符號位的值為0表示這個數為正數,符號位值為1表示這個樹為負數。由於符號位表示符號所以其不表示具體的值,除開符號位剩餘的bit位用來表示數值也就是數值位。比如1個字節的整數00000001,其中最高bit(最左邊)位的0為符號位,表示這個數為正數,數值位為1,所以其真值為1。同理2個字節的整數00000000_0000001,其真值也是1。

原碼、反碼和補碼

計算機只識別機器碼,其實也就是二進位數,並且使用最高bit位表示符號位。那麼兩個真值為8和-8的8位整數,它們在計算機內部的機器值是否就分別是00001000和10001000?其實並不是,這只是8和-8的原碼,而機器算計中的機器值是使用補碼存儲和計算的。

計算機中,正數的原碼、反碼和補碼是一樣的,所以上面那個例子中,真值為8的8位整數的機器值確實是00001000,但是-8就不是這麼回事了。負數的首先將原碼數值位按位取反得到反碼,然後再將反碼數值位加1之後則得到補碼。我們來看一下-8這個例子,其原碼為10001000,數值位按位取反之後的反碼為11110111,然後數值位加1之後的補碼為11111000。所以真值為-8的8位整數在計算機中的機器值為11111000,我們來看下面這張表

註:int8為8bit位整數佔用1byte,int16為16bit位整數佔用2byte。

剛說的是原碼轉補碼的步驟,其實補碼轉原碼的步驟是一樣的。首先正數的原碼補碼是一樣的不需要轉換,我們看負數11111000,首先將數值位按位取反得到10000111,然後再將數值位加1得到10001000。我們再來看一個8位的整數10000000,是不是發現這個數原碼和補碼是一樣的,那麼這個看起來像是「-0」的數是怎麼回事呢?其實可以將這個數看成是一個特殊值,它的真實含義就是最小值。8位的這種「-0」的真值為-128,16位的這種「-0」真值為-32768。所以只需要記住100...000這種補碼就是最小值就行,我們看下面的這張表

有兩對8bit位的整數4、8和4、-8,我們分別看一下他們在計算機中是怎麼做加法計算的。首先看4和8的補碼分別為00000100和00001000,只需要將每個bit位相加就行,結果為00001100,其真值為12。我們再來4和-8的計算,它們補碼分別為00000100和11111000,然後將它們按位相加(注意符號位也要做加法)得到11111100,其原碼為10000100,真值為-4。

再來看一下減法計算,比如8bit位的整數-8減去4,首先可以將4處理一下可以變為(-8) + (-4),這樣是不是就又變為了加法了?-8和-4的補碼分別為11111000和11111100,將它們按位相加得到補碼11110100(注意這是8位的整數,超出部分發生了溢出),轉換成原碼為10001100,真值為-12。

再來看一下乘法,比如8bit位的整數-8乘以13,他們的補碼分別為11111000和00001101。其中-8為被乘數,13為乘數,並且乘數有8個bit位,需要將被乘數按位與和位計算8次然後將結果相加,看如下分析:

1、被乘數的第0個bit位值為1,將被乘數乘以1然後左移0位得到:11111000;2、被乘數的第1個bit位值為0,將被乘數乘以0然後左移1位得到:00000000;3、被乘數的第2個bit位值為1,將被乘數乘以1然後左移2位得到;11100000;4、被乘數的第3個bit位值為1,將被乘數乘以1然後左移3位得到;11000000;5、被乘數的第4個bit位值為0,將被乘數乘以0然後左移4位得到;00000000;6、被乘數的第5個bit位值為0,將被乘數乘以0然後左移5位得到;00000000;7、被乘數的第6個bit位值為0,將被乘數乘以0然後左移6位得到;00000000;8、被乘數的第7個bit位值為0,將被乘數乘以0然後左移7位得到;00000000;由此可以得計算得到8組補碼(注意上面做位移涉及到的整數溢出,只能是8個bit位),然後將它們做加法得到10011000(也存在整數溢出)轉換為原碼為11101000,真值為-104。

至於除法則是使用交替加減法的方式,本文只是對計算原理做一下擴展,這裡不再繼續深入做介紹,如果有想了解的可以自行上網查詢。

通過上面的分析可以知道,使用補碼可以將所有計算都轉化為加法計算,這樣可以讓計算機底層對於整數(浮點數再此不做講解,有時間會再單獨寫一篇文章作介紹)計算變得簡單,反碼屬於歷史遺留,因為其存在±0的問題。

Java中的基本數據類型

在計算機程式語言中都會有數據類型的概念,數據類型是用來修飾變量的。不同數據類型所修飾的變量,其指代的數據在內存中佔用空間的大小(基本類型變量使用的空間、指針或引用變量指向的地址空間等,後面簡單稱數據類型佔用的內存空間)是固定的。即使在一些弱類型語言中,雖然變量可以不用顯示地聲明數據類型,但當第一次為變量賦值時,還是會隱式地為其附上數據類型屬性。

對於java來說,由於其具有跨平臺的特性,所以基本數據類型所佔用的內存空間大小(字節數)是固定的。我們來看一下java中的幾個基本數據類型:

註:jvm規範並沒有指明boolean類型佔用幾個字節的空間,所以根據jvm產品的不同,實現的方式也可能不同。最廣泛的說法是,jvm內部使用int代替boolean類型,也就是佔用4個字節。另外這裡沒有列出浮點數的大小範圍,由於本文只介紹整數,後面如果有時間則會單獨出一篇介紹浮點數的博文。

我們來看下面幾個例子

// 案例1,下面的10進位真值的寫法,但是當編譯器編譯完成之後,在內存中還是會以補碼的形式存在int value1 = 10;int value2 = -10;System.out.printf("value1=%d, value2=%d\n", value1, value2); // 結果為: value1=10, value2=-10// 案例2,下面是2進位補碼的寫法,在數字前面加上'0b'或者'0B','_'只是一個分隔符int value3 = 0b00000000_00000000_00000000_00001010; // 2進位int類型10的補碼int value4 = 0B11111111_11111111_11111111_11110110; // 2進位int類型-10的補碼System.out.printf("value3=%d, value4=%d\n", value3, value4); // 結果為: value3=10, value4=-10// 案例3,下面是16進位補碼的寫法,在數字前面加上'0x'或者'0X',大於9的數值使用a~f或A-F表示int value5 = 0x0000000a; // 16進位int類型10的補碼int value6 = 0Xfffffff6; // 16進位int類型-10的補碼System.out.printf("value5=%d, value6=%d\n", value5, value6); // 結果為: value5=10, value6=-10// 案例4,下面是8進位補碼的寫法,在數字前面加上'0'int value7 = 012; // 8進位int類型10的補碼int value8 = 037777777766; // 8進位int類型-10的補碼System.out.printf("value7=%d, value8=%d\n", value7, value8); // 結果為: value7=10, value8=-10/* * 注: 這裡不論是10進位還是16進位等方式寫的整數,在計算機內部都是以二進位補碼的形式體現, * 也就是上面案例2的中2進位的形式體現。 */額外說明一下,這些基本數據類型只會出現在線程棧中,或者再詳細一點,只會出現在線程棧的運行時棧幀(方法的工作空間)的局部變量表和操作數棧中。也就是說,只有在局部方法中才可以聲明基本數據類型的局部變量。對象的成員變量或者類的靜態變量即使是基本數據類型,最終也會被自動裝箱為包裝類型,然後在堆中開闢空間。 但也有例外,在現在的高性能jvm中一般都會有jit(即時編譯)系統,在逃逸分析時如果對象被判斷為未逃逸(對象不是入參、不是返回值並且也沒有被方法外部變量引用),則會做標量替換(拆分對象為基本數據類型)然後在線程棧或者CPU寄存器中分配空間,方法執行完成之後隨著運行時棧幀出棧而被回收,可減少GC的工作負載。

Java中的整數類型轉換

整數的基本類型之間可以互相轉換,甚至char類型都可以轉換為byte、short、int、long等類型,反之亦然。但是不同的數據類型,其所佔用的內存空間大小是不一樣的,那麼這裡就涉及到補全和溢出的問題了。

整數類型按所佔內存空間從小到大排序分別為byte、short、int、long,由佔用空間小的轉型為佔用空間大的為向上轉型,反之為向下轉型。java中類型轉換運算符為括號,括號中為轉換的目標類型,例如long value = (long) Integer.MAX_VALUE;。向上類型轉換可以隱式地完成,也就是說不需要顯示地編寫出類型轉換運算符例如long value = Integer.MAX_VALUE;。但是向下類型轉換時,可能會發生整數溢出(捨棄高字節位),所以必須顯式的寫出類型轉換運算符,例如short value = (short) Integer.MAX_VALUE;。

如果是向上轉型時,使用符號位的值填充高字節位。向下轉型時,直接舍掉高字節位。我們看下面兩張表,從上往下看為向下轉型,從下往上看則為向上轉型:

可以看到,不論轉換成什麼類型,最終的值還是不變的。我們看下面的案例:

// 案例1byte value = (byte) Short.MAX_VALUE; // Short.MAX_VALUE為short類型的最大值: 32767// 案例2short value = Byte.MIN_VALUE; // Byte.MIN_VALUE為byte類型的最小值: -128案例1為一個向下類型轉換,由於32767這個值超過了byte能表示的最大值,所以其必然會發生整數溢出。short類型的32767的二進位補碼為01111111_11111111,向下轉型為byte舍掉高位字節的二進位補碼為11111111,其值變為了-1。

案例2為一個向上類型轉換,byte類型的-128的二進位補碼為10000000,將其轉換為short類型之後的二進位補碼為11111111_10000000。我們知道雖然其表示的值沒有變還是-128,但是如果我們在向上類型轉換之後,還想讓原來的符號位表示數值,也就是得到byte類型-128這個值的無符號數,則可以做按位與計算int value = Byte.MIN_VALUE & 0xff;

Java中的字面量

Java中可以可以定義兩種類型的整數字面量,分別為int和long。例如int value = 10;或者long value = 10L;,可以看到其中long類型的字面量需要加上'L'類型的後綴,當然也可以是'l'。

Java中無法直接定義byte和short類型的字面量,但是如果這麼寫byte value = 127;編譯也沒錯,那麼這裡的127是不是就是byte類型的字面量呢?其實不是,這個127還是int類型的,只不過做了向下類型轉換而已。但是前面說向下類型轉換必須顯式的寫出類型轉換運算符,這裡沒有那麼是不是前面說錯了呢?其實也不是,int類型127的二進位補碼為00000000_00000000_00000000_01111111,向下轉型為byte類型之後的二進位補碼為01111111,那些被捨棄的0可以看做是填充位所以並沒有發生整數溢出。由於字面量是靜態不可變的值,編譯器在編譯的時候就知道其並不會發生整數溢出,所以就直接做了隱式類型轉換。但是我們來看字面量為128的int類型整數,其二進位補碼為00000000_00000000_00000000_10000000,轉換為byte類型之後的補碼為10000000,原本屬於數值位的1變為了符號位,這裡發生了整數溢出,所以需要顯式的加上類型轉換運算符byte value = (byte) 128;。

我們來看下面這些關於字面量的隱式類型轉換的案例

// 案例1byte value1 = 127;// 案例2,-128在byte能夠表示的數值範圍內,編譯器直接做了隱式類型轉換。byte value2 = -128; // 賦值給value1的二進位補碼為: 10000000// 案例3,Short.MAX_VALUE是一個常量,編譯器編譯的時候可以明確的知道其值為32767,所以編譯器會先計算出32767 - 32640的值然後賦值給value3變量byte value3 = Short.MAX_VALUE - 32640; // 賦值給value3的二進位補碼為: 01111111// 案例4,下面由於變量value4被final修飾,其值在編譯期間是不可變的,編譯器也能明確知道其值不會發生整數溢出final byte int value4 = 127;byte value5 = value4;// 案例5static final int value6 = 32767;void func() { short value7 = value6;}我們看這一行代碼long value = 2147483647,這是一個向上轉型的例子,將int類型的字面量2147483647轉換為long類型。但是如果字面量為2147483648就必須這麼寫long value = 2147483648L;,因為2147483648這個值已經超過了int類型的最大值,必須使用long類型的字面量表示。

內存對齊和有效位移

不管是四則運算還是位運算,參與計算的整數有可能是不同的數據類型,也就意味著它們在內存中的佔用的字節數不同,所以在計算的時候需要將轉換為相同的類型,也就是內存對齊。

如果是byte、short、int等類型的數據做計算,默認會將byte和short了類型的數據先轉換為int類型的數據然後在做計算。如果參與計算的數據中有long類型的數據,則會將非long類型的數據先轉換為long類型,然後在做計算。

位移計算的時候數據類型要麼是int類型要麼是long類型,也就是說計算的說要麼有32的bit位要麼有64個bit為,那麼我們做位移的時候是不是可以位移無限的bit位呢?當然不是,有效位移的位數為0到bit為數量(字寬)減去1,也就是說int的有效位移大小為0 ~ 31,long的有效位移數量為0 ~ 63。如果超出這個範圍的話則會與31或者63做按位與計算,比如int數據位移36位則實際位移為36 & 31 = 4。

Varints 128位可變長整型

通過前面的說明,大家應該對計算機中的整數有了清晰的理解。比如有一個int類型的整數,我們需要在網絡傳輸傳輸它,那麼發送方只需要傳輸4個字節的數據就行,接收方也只需要接收4個字節。比如我們傳輸一個值為10的int類型數據,大家可以知道其實只需要傳輸一個字節就行,但是誰也不能保證下一個傳輸的數據使用一個字節會不會溢出,所以這時候我們就需要設計一個可以變換字節數量的編解碼方式,並且數據接收方也能夠知道自己需要接受幾個字節,Varints就是為了解決這個問題的。

Varints是按小端字節序排列,也就是低位字節在前高位字節在後。每個字節的第7個bit位不表示數值,只是用來標識是否為最後一個字節,如果第7個bit位值為1則代表不是最後一個字節,如果值為0則代表為最後一個字節,如下表:

我們看上表中,紅色部分為標識是否最後一個字節的bit位,那麼這樣是不是就可以表示一個無窮大的整數了,不過一般也沒必要太大,就拿java來說,最大也就long類型的8個字節64個bit位大小。其實正真生產過程中應用所處理處理數據時,遇到小數值的概率要比遇到大數值的概率要大得多,所以varints可以在做網絡傳輸或者數據存儲時可以省不少流量和空間,而且可以便於擴展。不說別的,直接上代碼了:

public final class ByteUtil { private ByteUtil() {} public static byte[] enVarInt(int value) { int size = 0; byte[] temps = new byte[5]; for (; (value & 0xffffff80) != 0; value >>>= 7, ++size) { temps[size] = (byte) (value & 0x7f | 0x80); } temps[size] = (byte) value; byte[] result = new byte[size + 1]; System.arraycopy(temps, 0, result, 0, result.length); return result; } public static byte[] enVarInt(long value) { int size = 0; byte[] temps = new byte[10]; for (; (value & 0xffffffffffffff80L) != 0; value >>>= 7, ++size) { temps[size] = (byte) (value & 0x7fL | 0x80L); } temps[size] = (byte) value; byte[] result = new byte[size + 1]; System.arraycopy(temps, 0, result, 0, result.length); return result; } public static IntPair deVarInt(int offset, byte... buffer) { isLegalArg(offset >= 0 && offset < buffer.length, String.format("offset=%d, bufferLen=%d, Must meet: offset >= 0 && offset < %d", offset, buffer.length, buffer.length)); int bitSize = 0, result = 0, length = 0; for (; offset < buffer.length && bitSize < Integer.SIZE; ++offset) { int value = buffer[offset] & 0xff; result |= (value & 0x7f) << bitSize; bitSize += 7; ++length; if (0 == (value & 0x80)) { break; } } return IntPair.of(length, result); } public static IntLPair deVarLong(int offset, byte... buffer) { isLegalArg(offset >= 0 && offset < buffer.length, String.format("offset=%d, bufferLen=%d, Must meet: offset >= 0 && offset < %d", offset, buffer.length, buffer.length)); int bitSize = 0, length = 0; long result = 0; for (; offset < buffer.length && bitSize < Long.SIZE; ++offset) { int value = buffer[offset] & 0xff; result |= (value & 0x7fL) << bitSize; bitSize += 7; ++length; if (0 == (value & 0x80)) { break; } } return IntLPair.of(length, result); } private static void isLegalArg(boolean isLegalArg, String message) { if (!isLegalArg) { throw new IllegalArgumentException(message); } }}ZigZag

前面我們講解了varints可以省流量和空間,因為一般遇到小數值的概率要比遇到大數值的概率要大得多,同時我們也說了計算機內部是只是別補碼的,如果處理一個數值很小但是卻是負數的時候,單憑varints可就不能達到省流量和省空間的效果了。前面我們也講到符號位為整數的最高bit位,那麼即使一個負數的數值再小,整個整數看起來也不小,所以這時候就需要使用到ZigZag來吧符號位處理一下。

ZigZag編碼時,正數不做任何處理。對於負數則將整體數值位按位取反再左移一位,然後將符號位放到第0個bit位上,這樣處理之後就會得到一個與原來不一樣的整數,然後再按varints進行編碼。直接上ZigZag的代碼了:

public final class ByteUtil { private ByteUtil() {} public static int enZigZag(int value) { return (value << 1) ^ (value >> 31); } public static long enZigZag(long value) { return (value << 1) ^ (value >> 63); } public static int deZigZag(int value) { return (value >>> 1) ^ -(value & 1); } public static long deZigZag(long value) { return (value >>> 1) ^ -(value & 1); }}附加代碼

import java.util.Objects;public class IntLPair { private int left; private long right; public IntLPair() { } private IntLPair(int left, long right) { this.left = left; this.right = right; } public static IntLPair of(int left, long right) { return new IntLPair(left, right); } public int getInt() { return left; } public void setInt(int left) { this.left = left; } public long getLong() { return right; } public void setLong(long right) { this.right = right; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; IntLPair intLPair = (IntLPair) o; return left == intLPair.left && right == intLPair.right; } @Override public int hashCode() { return Objects.hash(left, right); } @Override public String toString() { return "IntLPair{" + "left=" + left + ", right=" + right + '}'; } }import java.util.Objects;public class IntLPair { private int left; private long right; public IntLPair() { } private IntLPair(int left, long right) { this.left = left; this.right = right; } public static IntLPair of(int left, long right) { return new IntLPair(left, right); } public int getInt() { return left; } public void setInt(int left) { this.left = left; } public long getLong() { return right; } public void setLong(long right) { this.right = right; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; IntLPair intLPair = (IntLPair) o; return left == intLPair.left && right == intLPair.right; } @Override public int hashCode() { return Objects.hash(left, right); } @Override public String toString() { return "IntLPair{" + "left=" + left + ", right=" + right + '}'; } }文章轉載自:https://www.cnblogs.com/lbole/p/14260496.html

相關焦點

  • 個人總結——二進位、十進位、十六進位轉換的方法
    近期和同事溝通時發現很多小夥伴多進位的轉換不太清晰,所以趁著周末自己總結了一下和大家分享想,下面先了解下定義。
  • 二進位、八進位、十六進位在現實當中有什麼意義?
    二進位二進位的出現是創歷史性的,在古代就有兩儀生四象,四象生八卦,八卦生萬物的說法,世間萬事萬物至少都有兩個狀態,比如生存/死亡、開/關、好/壞、高/低、大/小、長/短、胖/瘦等,這兩個狀態就可以使用二進位的0和1來表示。如今二進位主要運用於電子技術的數字電路當中,就比如計算機,最直接能夠識別的語言就是二進位語言。
  • 關於二進位、十進位、八進位、十六進位數據轉換計算方法詳細總結
    (1)十進位轉換為八進位 十進位轉換成八進位有兩種方法: 1)間接法:先將十進位轉換成二進位,然後將二進位又轉換成八進位 2)直接法:前面我們講過,八進位是由二進位衍生而來的,因此我們可以採用與十進位轉換為二進位相類似的方法,還是整數部分的轉換和小數部分的轉換
  • 二進位、八進位、十進位與十六進位
    例如對於二進位來說,該規則是「滿二進一,借一當二」;對於十進位來說,該規則是「滿十進一,借一當十」。其他進位也是這樣。然後把第一次得到的餘數作為二進位的個位,第二次得到的餘數作為二進位的十位,依次類推,最後一次得到的小於2的商作為二進位的最高位,這樣由商+餘數組成的數字就是轉換後二進位的值(整數部分用除2取餘法);小數部分則先乘2,然後獲得運算結果的整數部分,將結果中的小數部分再次乘2,直到小數部分為零。
  • 二進位,八進位,十進位,十六進位轉換詳解~
    ①、數碼:用來表示進位數的元素。                                二進位:0,1。                                八進位:0,1,2,3,4,5,6,7                                十進位:0,1,2,3,4,5,6,7,8,9。
  • 二進位、八進位和十六進位之間轉換
    我們不妨將思維拓展一下,既然可以用 0~9 共十個數字來表示數值,那麼也可以用0、1兩個數字來表示數值,這就是二進位(Binary)。例如,數字 0、1、10、111、100、1000001 都是有效的二進位。在計算機內部,數據都是以二進位的形式存儲的,二進位是學習編程必須掌握的基礎。
  • 10、進位轉換:二進位、八進位、十六進位、十進位之間的轉換
    1) 二進位整數和八進位整數之間的轉換二進位整數轉換為八進位整數時,每三位二進位數字轉換為一位八進位數字,運算的順序是從低位向高位依次進行,高位不足三位用零補齊。下圖演示了如何將二進位整數 1110111100 轉換為八進位:
  • 計算機的語言——二進位,十進位、八進位、十六進位與二進位之間的轉換
  • 二進位轉換為十進位和十進位轉換為二進位的方法
    各位小夥伴們大家好,在之前的文章中小編也介紹了關於二進位轉十進位的方法,這次小編知道了一個更簡單的方法,具體如下:比如我們要把28轉為二進位:28轉換為2進位先用2的n次方來表示28這個數,然後用2的n次方乘以1或者乘以0,相加來湊成與之相等的數,得到的1或者是0,根據這個表格,從左往右把二進位數字湊在一起,11100就是28的二進位了。
  • 二進位,八進位,十進位,十六進位之間的轉換
    什麼是二進位二進位是計算技術中廣泛採用的一種數制。二進位數據是用0和1兩個數碼來表示的數。它的基數為2,進位規則是「逢二進一」,借位規則是「借一當二」,由18世紀德國數理哲學大師萊布尼茲發現。當前的計算機系統使用的基本上是二進位系統,數據在計算機中主要是以補碼的形式存儲的。
  • 二進位轉換十進位,十進位轉換二進位
    如果把一個十進位的數轉換成二進位的數 , 直接把數除 以二 , 餘數為一就寫1 , 整除 , 就寫0 , 一直除完為止
  • scratch製作「二進位轉十進位」
    我們之前學習並製作過「十進位轉二進位」的小程序:如圖:學生作品2「十進位轉二進位」接下來我們製作「二進位轉十進位」的小程序。樣例輸入:11011樣例輸出:27方法1,從前向後遍歷新建變量:二進位,用於存儲回答中輸入的二進位數字長度,輸入二進位數字的長度(scratch相對簡單,不用區分變量的類型)十進位,初始化為0,用於累加轉換好的數字和最後的輸出。
  • 二進位、十進位和十六進位
    二進位就是逢二進位,它的一個位只有兩個值:0 和 1,但它卻是實現計算機系統的最基本的理論基礎,計算機(包括單片機)晶片是基於成萬上億個的開關管組合而成的,他們每一個都只能有開和關兩種狀態,再難找出第三個狀態了(不要辯解半開半關這個狀態,它是不穩定態,是極力避免的),所以他們只能對應於二進位的 1 和 0 兩個值,而沒有 2、3、4......,理解二進位對於理解計算機的本質很有幫助。
  • 進位轉換 二進位轉十進位
    上節課我們學習了十進位轉換成二進位的方法,那二進位轉換十進位是怎麼轉換的呢?
  • 清晰說明十進位如何快速轉二進位,助力考生
    小編曾經總結過這樣的一篇文章,關於二進位、十進位、八進位、十六進位數據轉換計算方法詳細總結今天之所以又寫這篇文章,一是補充上文中的缺憾,沒有分享十進位到二進位最快的方法;再就是響應平臺號召,助力高考。那麼高考會考嗎?
  • 進位詳解:二進位、八進位和十六進位
    二進位我們不妨將思維拓展一下,既然可以用 0~9 共十個數字來表示數值,那麼也可以用0、1兩個數字來表示數值,這就是二進位(Binary)。例如,數字 0、1、10、111、100、1000001 都是有效的二進位。在計算機內部,數據都是以二進位的形式存儲的,二進位是學習編程必須掌握的基礎。本節我們先講解二進位的概念,下節講解數據在內存中的存儲,讓大家學以致用。
  • 二進位、八進位、十進位和十六進位數之間的轉換方法
    2、特點:每個數的數位上只能是0,1兩個數字;二進位數中最大數字是1,最小數字是0;基數為2;比如:10011010與00101011是兩個二進位數。2、特點:每個數的數位上只能是0、1、2、3、4、5、6、7八個數字;八進位數中最大數字是7,最小數字是0;基數為8;比如:(1347)8與(62435)8是兩個八進位數。
  • 十進位轉二、八、十六進位
    小知識:轉成二進位主要有以下幾種:正整數轉二進位,負整數轉二進位,小數轉二進位;1、  正整數轉成二進位。要點一定一定要記住哈:除二取餘,然後倒序排列,高位補零。也就是說,將正的十進位數除以二,得到的商再除以二,依次類推知道商為零或一時為止,然後在旁邊標出各步的餘數,最後倒著寫出來,高位補零就OK咧。哎呀,還是舉例說明吧,比如42轉換為二進位,如圖1所示操作。二進位如何轉十進位,十進位如何轉二進位42除以2得到的餘數分別為010101,然後咱們倒著排一下,42所對應二進位就是101010.
  • 計算機基礎進位轉換(二進位、八進位、十進位、十六進位)
    1.十進位轉R進位1.1 十進位轉二進位十進位整數轉二進位十進位整數轉換成二進位採用「除2倒取餘」,十進位小數轉換成二進位小數採用
  • 二進位、八進位、十進位、十六進位之間的轉換
    反過來,當我們看到 FD時,如何迅速將它轉換為二進位數呢?先轉換F:        看到F,我們需知道它是15(可能你還不熟悉A~F這六個數),然後15如何用8421湊呢?應該是8 + 4 + 2 + 1,所以四位全為1 :1111。接著轉換 D:        看到D,知道它是13,13如何用8421湊呢?