الثنائي والثماني والست عشري (وتُعرَف أيضًا بـ hex) أنظمة أعداد مختلفة بأساسات مختلفة. الثنائي أساسه 2، والثماني أساسه 8، والست عشري أساسه 16. الأعداد الصحيحة العادية أساسها 10 في Crystal. الثنائي والثماني والست عشري جميعها تمثيلات للأعداد الصحيحة. وهذا يعني أنها تمثّل الأعداد الموجبة والسالبة (بما في ذلك الصفر) دون كسور أو أعداد عشرية، وتدعم كل العمليات التي يمكننا إجراؤها على الأعداد الصحيحة.
الثنائي هو نظام أعداد أساسه 2، ويستخدم الرقمين 0 و1 فقط. وهو يمثّل عادةً الحالتين 0 ("إيقاف") و1 ("تشغيل") لتدفق الكهرباء عبر الترانزستورات والمفاتيح في الحواسيب، وكذلك الشحنات الموجبة والسالبة في وسائط التخزين المغناطيسي. يستطيع الثنائي تمثيل كل الأعداد الصحيحة المستخدمة في الأساس 10.
مقتطف من نظام الأساس 2 يبدو هكذا، مع أنه يستمر بلا نهاية ولا يتوقف عند 128:
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|---|---|---|---|---|---|---|---|
| 2 ** 7 | 2 ** 6 | 2 ** 5 | 2 ** 4 | 2 ** 3 | 2 ** 2 | 2 ** 1 | 2 ** 0 |
فإذا أردنا تمثيل العدد 6، فسيكون في الثنائي: 110
| القيمة المنزلية | 4 | 2 | 1 |
|---|---|---|---|
| العدد الثنائي | 1 | 1 | 0 |
وتكون العملية: 4 + 2 + 0 = 6
مثال آخر: 19
| القيمة المنزلية | 16 | 8 | 4 | 2 | 1 |
|---|---|---|---|---|---|
| العدد الثنائي | 1 | 0 | 0 | 1 | 1 |
سيكون العدد الثنائي: 10011
وتكون العملية: 16 + 0 + 0 + 2 + 1 = 19
في Crystal، يمكننا تمثيل القيم الثنائية الحرفية باستخدام السابقة 0b.
إذا كتبنا 0b10011، فسيفسّره Crystal على أنه عدد ثنائي ويحوّله إلى الأساس 10.
0b10011
# => 19
typeof(0b10011)
# => Int32
إذا كتبت عددًا بالسابقة 0b لا ينتمي إلى النظام الثنائي، فسيؤدي ذلك إلى خطأ في التصريف.
0b10211
# => Error: unexpected token: "211"
بما أن الأعداد الثنائية أعداد صحيحة، فيمكننا إجراء كل العمليات عليها التي نجريها على الأعداد الصحيحة.
0b10011 + 0b10011
# => 38
0b10011 * 0b10011
# => 361
0b10011 / 3
# => 6.333333333333333
سيحوّل Crystal القيمة الثنائية الحرفية تلقائيًا إلى Int32.
لتحويل Int32 إلى تمثيل ثنائي، استخدم الطريقة <int>.to_s(base) مع ضبط الوسيط base على القيمة 2.
ستُرجع الطريقة تمثيلًا نصيًا للعدد الثنائي:
19.to_s(2)
# => "10011"
لتحويل تمثيل نصي لعدد ثنائي إلى عدد صحيح، يمكننا استخدام الطريقة <int>.to_i(base)، بتمرير الأساس (2) كوسيط:
"10011".to_i(2)
# => 19
إعطاء الأساس الخطأ (أو تمثيل ثنائي غير صالح) سيؤدي إلى استثناء ArgumentError:
"011021".to_i(2)
# => Invalid Int32: "011021" (ArgumentError)
هناك طرق معيّنة يمكن استخدامها على الأعداد الصحيحة للحصول على معلومات عن التمثيل الثنائي للعدد.
ستُرجع <int>.bit_length عدد البتات اللازمة لتمثيل العدد:
19.bit_length
# => 5
ستُرجع <int>.bit(index) البتة عند الفهرس المعطى، بدءًا من اليمين (البتة الأقل أهمية):
19.bit(0)
# => 1
0b10011.bit(1)
# => 1
الثماني هو نظام أعداد أساسه 8. ويستخدم الأرقام 0 و1 و2 و3 و4 و5 و6 و7.
في Crystal، يمكننا تمثيل الأعداد الثمانية باستخدام السابقة 0o.
وكما في الثنائي، يحوّل Crystal التمثيل الثماني تلقائيًا إلى Int32.
0o123
# => 83
إضافة السابقة 0o إلى عدد لا ينتمي إلى النظام الثماني سيؤدي إلى خطأ في التصريف.
وكما في الثنائي، يمكننا استخدام الطريقة <int>.to_s(base) لتحويل Int32 إلى تمثيل ثماني.
ويمكننا استخدام الطريقة <int>.to_i(base) لتحويل تمثيل ثماني إلى Int32.
83.to_s(8)
# => "123"
"123".to_i(8)
# => 83
وكما في الثنائي، سيؤدي إعطاء الأساس الخطأ إلى استثناء ArgumentError.
الست عشري هو نظام أعداد أساسه 16. ويستخدم الأرقام من 0 إلى 9 والحروف A وB وC وD وE وF. الحرف A يساوي 10، وB يساوي 11، وC يساوي 12، وD يساوي 13، وE يساوي 14، وF يساوي 15.
يمكننا تمثيل الأعداد الست عشرية في Crystal باستخدام السابقة 0x.
وكما في الثنائي والثماني، سيحوّل Crystal القيم الست عشرية الحرفية تلقائيًا إلى Int32.
#=> 0x123
291
إضافة السابقة 0x إلى عدد غير ست عشري سيؤدي إلى خطأ في التصريف.
وكما في الثنائي، يمكننا استخدام الطريقة <int>.to_s(base) لتحويل Int32 إلى تمثيل ست عشري.
ويمكننا استخدام الطريقة <int>.to_i(base) لتحويل تمثيل ست عشري إلى Int32.
291.to_s(16)
# => "123"
"123".to_i(16)
# => 291
وكما في الثنائي والثماني، سيؤدي إعطاء الأساس الخطأ إلى استثناء ArgumentError.
عند تحويل عدد إلى تمثيل نصي، يمكننا تحديد دقة العدد.
أي الحد الأدنى لعدد الأرقام المستخدمة لتمثيل العدد.
إذا كان عدد أرقام العدد أقل من الدقة، فستُضاف أصفار بادئة إلى التمثيل النصي.
ويتم ذلك بتمرير الوسيط precision إلى الطريقة <int>.to_s(<base>, precision: <value>).
291.to_s(16, precision: 5)
# => "00123"
543.to_s(precision: 2)
# => "543"
سئم صديقك من الدفع مقابل برامج تحرير الصور، وقرر أن يكتب برنامجه الخاص. قرّر صديقك أن يسمّي البرنامج الجديد Foto Fusionist.
Foto Fusionist برنامج لتحرير الصور يمكنه القيام بالكثير من الأشياء، لكنك لم تُنجز سوى القليل منها حتى الآن. لكن صديقك سعيد جدًا بالتقدّم الذي أُحرز، وطلب منك إنجاز بعض الميزات الإضافية.
في الميزة الأولى، يريد صديقك أن يكون قادرًا على تحويل التمثيل الثنائي لعدد إلى عدد صحيح. يُفعل ذلك لأن البرنامج سيتمكن من قراءة التمثيل الثنائي لقناة لونية وتحويله إلى عدد صحيح.
نفّذ الطريقة FotoFusionist.binary_to_int التي تأخذ وسيطًا binary من النوع String.
ينبغي أن تُرجع الطريقة التمثيل الصحيح للعدد الثنائي.
FotoFusionist.binary_to_int("10011")
# => 19
الميزة الثانية التي يريدها صديقك هي أن يكون قادرًا على الحصول على البت الأقل أهمية من عدد صحيح. البت الأقل أهمية هو البت الواقع في أقصى اليمين. سُمّي البت الأقل أهمية لأنه يحمل أقل قيمة.
نحتاج إلى البت الأقل أهمية لتقييم ما إذا كان يمكن تحسين الصورة بتقليل عدد البتات المستخدمة لتمثيل قناة الألوان.
نفّذ الطريقة FotoFusionist.least_significant_bit التي تأخذ وسيطًا number من النوع Int32.
ينبغي أن تُرجع الطريقة البت الأقل أهمية للعدد.
FotoFusionist.least_significant_bit(0b10011)
# => 1
FotoFusionist.least_significant_bit(0b10010)
# => 0
الميزة الثالثة التي يريدها صديقك هي أن يكون قادرًا على الحصول على القيمة الست عشرية من قناة الألوان. نحتاج إلى القيمة الست عشرية لتتمكن من تحويل قناة الألوان إلى تمثيل ست عشري، ويجب أن يتكوّن التمثيل الست عشري المعطى من رقمين.
نفّذ الطريقة FotoFusionist.hex_value التي تأخذ وسيطًا number من النوع Int32.
ينبغي أن تُرجع الطريقة القيمة الست عشرية للعدد بصيغة String.
FotoFusionist.hex_value(19)
# => "13"
الميزة الرابعة التي يريدها صديقك هي أن يكون قادرًا على الحصول على القيمة الست عشرية من لون RGB. نحتاج إلى ذلك حتى يتمكن المستخدم من الحصول على تمثيل اللون في سلسلة نصية واحدة. لون RGB هو لون يتمثّل بثلاث قنوات لونية: الأحمر والأخضر والأزرق. تُمثَّل كل قناة لونية بعدد يتراوح بين 0 و255.
القيمة الست عشرية للون RGB هي تمثيل للون في النظام الست عشري، بحيث تأتي قناة اللون الأحمر أولًا، ثم قناة اللون الأخضر، وأخيرًا قناة اللون الأزرق.
نفّذ الطريقة FotoFusionist.hex_value_from_rgb التي تأخذ ثلاثة وسائط: red وgreen وblue من النوع Int32.
ينبغي أن تُرجع الطريقة القيمة الست عشرية للون RGB بصيغة String.
FotoFusionist.hex_value_from_rgb(255, 0, 0)
# => "ff0000"
سجّل في Exercism لتتعلّم وتتقن Crystal عبر 26 مفهومًا142 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.