تقدّم 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.
سجّل في Exercism لتتعلّم وتتقن C# عبر 62 مفهومًا178 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.