學習軌道
/
C#
C#
/
練習
/
極致最佳化的遙測
極致最佳化的遙測

極致最佳化的遙測

學習練習

簡介

整數

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 位元組的緩衝區(視需要補上尾端的零)。

1. 將整數值編碼成可傳送的格式

請實作靜態方法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 };

2. 解碼接收到的緩衝區

請實作靜態方法TelemetryBuffer.FromBuffer(),解碼接收到的緩衝區,並以long的形式回傳該值。

TelemetryBuffer.FromBuffer(new byte[] {0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0 })
// => 2147483647

如果前綴位元組的值並非預期值,就應該回傳0。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟
C# Exercism

準備好開始 極致最佳化的遙測 了嗎?

註冊 Exercism,透過 62 個概念178 個練習 和真人引導來學習並精通 C#,全部免費。