مسیرها
/
C#
C#
/
تمرین‌ها
/
تله‌متری فوق‌بهینه
تله‌متری فوق‌بهینه

تله‌متری فوق‌بهینه

تمرین یادگیری

مقدمه

اعداد صحیح

‏#C، مانند بسیاری از زبان‌های ایستا، تعدادی نوع ارائه می‌دهد که اعداد صحیح را نمایش می‌دهند و هرکدام بازه‌ی مقادیر خودش را دارد. در پایین‌ترین حد، نوع sbyte حداقل مقدار -۱۲۸ و حداکثر مقدار ۱۲۷ را دارد. مانند همه‌ی نوع‌های صحیح، این مقادیر به شکل <type>.MinValue و <type>.MaxValue در دسترس هستند. در بالاترین حد، نوع long حداقل مقدار -۹,۲۲۳,۳۷۲,۰۳۶,۸۵۴,۷۷۵,۸۰۸ و حداکثر مقدار ۹,۲۲۳,۳۷۲,۰۳۶,۸۵۴,۷۷۵,۸۰۷ را دارد. در این میان، نوع‌های short و int قرار دارند.

این بازه‌ها بر اساس عرض ذخیره‌سازیِ نوع که سیستم تخصیص می‌دهد، تعیین می‌شوند. برای مثال، یک byte از ۸ بیت و یک long از ۶۴ بیت استفاده می‌کند.

هر یک از نوع‌های بالا با یک معادل بدون علامت جفت شده است: sbyte/byte، short/ushort، int/uint و long/ulong. در همه‌ی موارد، بازه‌ی مقادیر از ۰ تا منفیِ حداکثرِ علامت‌دار ضربدر ۲ به‌علاوه‌ی ۱ است.

نوع عرض حداقل حداکثر
sbyte ۸ بیت -۱۲۸ +۱۲۷
short ۱۶ بیت -۳۲_۷۶۸ +۳۲_۷۶۷
int ۳۲ بیت -۲_۱۴۷_۴۸۳_۶۴۸ +۲_۱۴۷_۴۸۳_۶۴۷
long ۶۴ بیت -۹_۲۲۳_۳۷۲_۰۳۶_۸۵۴_۷۷۵_۸۰۸ +۹_۲۲۳_۳۷۲_۰۳۶_۸۵۴_۷۷۵_۸۰۷
byte ۸ بیت ۰ +۲۵۵
ushort ۱۶ بیت ۰ +۶۵_۵۳۵
uint ۳۲ بیت ۰ +۴_۲۹۴_۹۶۷_۲۹۵
ulong ۶۴ بیت ۰ +۱۸_۴۴۶_۷۴۴_۰۷۳_۷۰۹_۵۵۱_۶۱۵

یک متغیر (یا عبارت) از یک نوع را می‌توان به‌سادگی به نوع دیگری تبدیل کرد. برای نمونه، در یک عملیات انتساب، اگر نوع مقداری که انتساب داده می‌شود (lhs) تضمین کند که مقدار در بازه‌ی نوعی که به آن انتساب داده می‌شود (rhs) قرار می‌گیرد، آنگاه انتساب ساده است:

uint ui = uint.MaxValue;
ulong ul = ui;    // no problem

از سوی دیگر، اگر بازه‌ی نوعِ مبدأ زیرمجموعه‌ای از بازه‌ی مقادیر نوعِ مقصد نباشد، آنگاه حتی اگر مقدار خاص در بازه‌ی مقصد قرار داشته باشد، به یک تبدیل نوع، یعنی عملگر ()، نیاز است:

short s = 42;
uint ui = (uint)s;

تبدیل بیت

کلاس BitConverter روشی راحت برای تبدیل نوع‌های صحیح به آرایه‌های بایت و برعکس فراهم می‌کند.

دستورالعمل‌ها

کار روی پروژه‌ی ماشین کنترل از راه دور ادامه دارد. پهنای باند در سامانه‌ی تله‌متری بسیار محدود است و از شما خواسته شده است که یک پروتکل پیام برای انتقال داده‌های تله‌متری پیاده‌سازی کنید.

داده‌ها در یک بافر (آرایه‌ی بایت) منتقل می‌شوند. هنگام ارسال اعداد صحیح، با به‌کارگیری پروتکلی که در ادامه توضیح داده شده است، اندازه‌ی بافر کاهش می‌یابد.

هر مقدار باید در کوچک‌ترین نوع صحیح ممکن نمایش داده شود (انواع byte و sbyte لحاظ نشده‌اند، چون صرفه‌جویی ناچیز خواهد بود):

از تا نوع
۴٬۲۹۴٬۹۶۷٬۲۹۶ ۹٬۲۲۳٬۳۷۲٬۰۳۶٬۸۵۴٬۷۷۵٬۸۰۷ long
۲٬۱۴۷٬۴۸۳٬۶۴۸ ۴٬۲۹۴٬۹۶۷٬۲۹۵ uint
۶۵٬۵۳۶ ۲٬۱۴۷٬۴۸۳٬۶۴۷ int
۰ ۶۵٬۵۳۵ ushort
منفی ۳۲٬۷۶۸ منفی ۱ short
منفی ۲٬۱۴۷٬۴۸۳٬۶۴۸ منفی ۳۲٬۷۶۹ int
منفی ۹٬۲۲۳٬۳۷۲٬۰۳۶٬۸۵۴٬۷۷۵٬۸۰۸ منفی ۲٬۱۴۷٬۴۸۳٬۶۴۹ long

مقدار باید به تعداد بایت مناسب برای نوع تخصیص‌یافته‌اش تبدیل شود. بافر کامل شامل یک بایت است که شمار بایت‌های اضافی در بافر را نشان می‌دهد (بایت پیشوند) و پس از آن بایت‌هایی قرار می‌گیرند که عدد صحیح را در خود دارند (بایت‌های داده).

برخی از انواع از تعداد بایت یکسانی استفاده می‌کنند (مثلاً انواع uint و int). به‌طور معمول، آن‌ها بایت پیشوند یکسانی می‌داشتند، اما این کار رمزگشایی را دشوار می‌کرد. برای مقابله با این مشکل، پروتکل ترفند کوچکی به کار می‌برد: برای انواع علامت‌دار، مقدار بایت پیشوند برابر است با 256 منهای شمار بایت‌های اضافی در بافر.

در ارتباط، فقط بایت پیشوند و شمار بایت‌های بعدی که با پیشوند مشخص می‌شوند فرستاده می‌شوند. در داخل، هم روال‌های ارسال و هم روال‌های دریافت از یک بافر ۹ بایتی استفاده می‌کنند (در صورت لزوم با صفرهای انتهایی).

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 ثبت‌نام کنید تا C# را همراه با 62 مفهوم178 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.