C# 和許多靜態型別語言一樣,提供了多種代表整數的型別,每種型別各有自己的值範圍。在範圍最小的一端,sbyte型別的最小值是 -128,最大值是 127。就像所有整數型別一樣,這些值可以透過<type>.MinValue和<type>.MaxValue取得。在範圍最大的一端,long型別的最小值是 -9,223,372,036,854,775,808,最大值是 9,223,372,036,854,775,807。介於兩者之間的是short和int型別。
這些範圍取決於系統為該型別配置的儲存寬度。例如,byte使用 8 個位元,long則使用 64 個位元。
上述每種型別都有一個對應的不帶正負號版本:sbyte/byte、short/ushort、int/uint和long/ulong。在所有情況下,值的範圍都是從 0 到負的帶正負號最大值乘以 2 再加 1。
| 型別 | 寬度 | 最小值 | 最大值 |
|---|---|---|---|
| sbyte | 8 位元 | -128 | +127 |
| short | 16 位元 | -32_768 | +32_767 |
| int | 32 位元 | -2_147_483_648 | +2_147_483_647 |
| long | 64 位元 | -9_223_372_036_854_775_808 | +9_223_372_036_854_775_807 |
| byte | 8 位元 | 0 | +255 |
| ushort | 16 位元 | 0 | +65_535 |
| uint | 32 位元 | 0 | +4_294_967_295 |
| ulong | 64 位元 | 0 | +18_446_744_073_709_551_615 |
一個型別的變數(或運算式)可以輕鬆轉換成另一個型別。舉例來說,在指定運算中,如果被指定的值的型別(lhs)能確保該值落在被指定目標的型別範圍內(rhs),那就只需要一個簡單的指定:
uint ui = uint.MaxValue;
ulong ul = ui; // no problem
另一方面,如果來源型別的範圍不是目標型別值範圍的子集,即使該特定值落在目標型別的範圍內,仍然需要進行轉型,也就是()運算:
short s = 42;
uint ui = (uint)s;
BitConverter類別提供了在整數型別和位元組陣列之間來回轉換的便利方式。
遙控車專案的開發仍在持續進行。遙測系統的頻寬十分寶貴,因此有人請你實作一套訊息協定,用來傳遞遙測資料。
資料是以緩衝區(位元組陣列)的形式傳輸。傳送整數時,會採用以下所述的協定來縮小緩衝區的大小。
每個值都應該用盡可能最小的整數型別來表示(不包含 byte 和 sbyte 型別,因為省下的空間微不足道):
| 從 | 到 | 型別 |
|---|---|---|
| 4_294_967_296 | 9_223_372_036_854_775_807 | long |
| 2_147_483_648 | 4_294_967_295 | uint |
| 65_536 | 2_147_483_647 | int |
| 0 | 65_535 | ushort |
| -32_768 | -1 | short |
| -2_147_483_648 | -32_769 | int |
| -9_223_372_036_854_775_808 | -2_147_483_649 | long |
這個值應該轉換成其指定型別所對應的位元組數。完整的緩衝區包含一個指出緩衝區中額外位元組數量的位元組(前綴位元組),後面接著存放整數的位元組(資料位元組)。
有些型別使用的位元組數相同(例如 uint 和 int 型別)。一般來說,它們會有相同的_前綴位元組_,但這會讓解碼變得麻煩。為了解決這個問題,這套協定用了一個小技巧:對於帶正負號的型別,其_前綴位元組_的值是256減去緩衝區中額外位元組的數量。
通訊時只會傳送前綴位元組,以及前綴所指示數量的後續位元組。在內部,傳送和接收的常式都會使用一個 9 位元組的緩衝區(視需要補上尾端的零)。
請實作靜態方法TelemetryBuffer.ToBuffer(),將傳入方法的參數編碼成緩衝區。
// Type: ushort, bytes: 2, signed: no, prefix byte: 2
TelemetryBuffer.ToBuffer(5)
// => {0x2, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
// Type: int, bytes: 4, signed: yes, prefix byte: 256 - 4
TelemetryBuffer.ToBuffer(Int32.MaxValue)
// => {0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0 };
請實作靜態方法TelemetryBuffer.FromBuffer(),解碼接收到的緩衝區,並以long的形式回傳該值。
TelemetryBuffer.FromBuffer(new byte[] {0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0 })
// => 2147483647
如果前綴位元組的值並非預期值,就應該回傳0。