تنسيق الفاصلة العائمة مزدوج الدقة

تنسيق الفاصلة العائمة ذو الدقة المزدوجة (يسمى أحيانًا FP64 أو float64 ) هو تنسيق أرقام الفاصلة العائمة ، ويشغل عادةً 64 بت في ذاكرة الكمبيوتر؛ وهو يمثل نطاقًا واسعًا من القيم العددية باستخدام فاصلة أساس عائمة .

يمكن اختيار الدقة المزدوجة عندما يكون نطاق أو دقة الدقة المفردة غير كافية.

في معيار IEEE 754 ، يُشار رسميًا إلى تنسيق الأساس 2 ذي 64 بت باسم binary64 ؛ وكان يُطلق عليه اسم double في معيار IEEE 754-1985 . يحدد معيار IEEE 754 تنسيقات إضافية للأعداد العشرية، بما في ذلك دقة مفردة أساس 2 ذات 32 بت ، ومؤخرًا، تمثيلات أساس 10 ( العدد العشري ).

كانت لغة فورتران من أوائل لغات البرمجة التي وفرت أنواع بيانات الفاصلة العائمة . قبل اعتماد معيار IEEE 754-1985 على نطاق واسع، كان تمثيل وخصائص أنواع بيانات الفاصلة العائمة يعتمد على الشركة المصنعة للحاسوب ونوعه، وعلى قرارات مطوري لغات البرمجة. على سبيل المثال، كان نوع بيانات الدقة المزدوجة في لغة GW-BASIC هو تنسيق الفاصلة العائمة MBF ذو 64 بت .

تنسيق الفاصلة العائمة الثنائية ذو الدقة المزدوجة IEEE 754: binary64

يُعدّ نظام الفاصلة العائمة الثنائي ذو الدقة المزدوجة تنسيقًا شائع الاستخدام على أجهزة الكمبيوتر الشخصية، نظرًا لنطاقه الأوسع مقارنةً بنظام الفاصلة العائمة أحادي الدقة، على الرغم من تكلفته من حيث الأداء وعرض النطاق الترددي. ويُعرف هذا النظام اختصارًا بـ double . ويحدد معيار IEEE 754 أن نظام binary64 يتميز بما يلي:

تحدد بتة الإشارة إشارة الرقم (بما في ذلك عندما يكون هذا الرقم صفرًا، وهو رقم ذو إشارة ).

حقل الأس هو عدد صحيح غير مُوَقَّع مكون من 11 بت، يتراوح من 0 إلى 2047، بصيغة مُحَوَّلة : قيمة الأس 1023 تُمثِّل الصفر الفعلي. تتراوح الأسس من -1022 إلى +1023 لأن الأسس -1023 (جميعها أصفار) و+1024 (جميعها آحاد) محجوزة لأعداد خاصة.

تُتيح دقة المعامل 53 بت دقة تتراوح بين 15 و17 رقمًا عشريًا معنويًا ( 2⁻⁵³  1.11  ×  10⁻¹⁶ ). إذا تم تحويل سلسلة عشرية تحتوي على 15 رقمًا معنويًا على الأكثر إلى تنسيق IEEE 754 ذي الدقة المزدوجة، مما يُعطي رقمًا عاديًا، ثم تم تحويلها مرة أخرى إلى سلسلة عشرية بنفس عدد الأرقام، فيجب أن تتطابق النتيجة النهائية مع السلسلة الأصلية. وإذا تم تحويل رقم IEEE 754 ذي الدقة المزدوجة إلى سلسلة عشرية تحتوي على 17 رقمًا معنويًا على الأقل، ثم تم تحويله مرة أخرى إلى تمثيل ذي دقة مزدوجة، فيجب أن تتطابق النتيجة النهائية مع الرقم الأصلي. [ 1 ]

يُكتب التنسيق بحيث يكون للجزء الكسري بت صحيح ضمني قيمته 1 (باستثناء البيانات الخاصة، انظر ترميز الأس أدناه). مع ظهور 52 بتًا من الجزء الكسري (F) في تنسيق الذاكرة، فإن الدقة الإجمالية هي 53 بتًا (حوالي 16 رقمًا عشريًا، 53 log 10 (2) ≈ 15.955). يتم ترتيب البتات كما يلي:

القيمة الحقيقية التي تفترضها بيانات ذات دقة مزدوجة 64 بت مع أس متحيز معينهـ{\displaystyle E} والكسر ذو 52 بت هو

(-1)لافتة(1.ب51ب50...ب0)2×2هـ-1023{\displaystyle (-1)^{\text{sign}}(1.b_{51}b_{50}...b_{0})_{2}\times 2^{E-1023}}

أو

(-1)لافتة(1+أنا=152ب52-أنا2-أنا)×2هـ-1023{\displaystyle (-1)^{\text{sign}}\left(1+\sum _{i=1}^{52}b_{52-i}2^{-i}\right)\times 2^{E-1023}}

بين 2⁵² = 4,503,599,627,370,496 و2⁵³ = 9,007,199,254,740,992 ، الأعداد القابلة للتمثيل هي الأعداد الصحيحة فقط. أما في النطاق التالي، من 2⁵³ إلى 2⁵⁴ ، فكل شيء مضروب في 2، لذا فإن الأعداد القابلة للتمثيل هي الأعداد الزوجية، وهكذا. وعلى العكس، في النطاق السابق من 2⁵¹ إلى 2⁵² ، تكون المسافة بين الأرقام 0.5، وهكذا.

المسافة كنسبة من الأعداد في النطاق من 2n إلى 2n + 1 هي 2n - 52. وبالتالي ، فإن أقصى خطأ نسبي في التقريب عند تقريب عدد إلى أقرب عدد قابل للتمثيل ( إبسيلون الآلة ) هو 2 - 53 .

يُتيح عرض الأسّ البالغ 11 بت تمثيل الأعداد بين 10⁻³⁰⁸ و10³⁰⁸ بدقة كاملة تتراوح بين 15 و 17 رقمًا عشريًا. وبالتضحية بالدقة، يسمح التمثيل غير الطبيعي بقيم أصغر تصل إلى حوالي 5  ×  10⁻³²⁴ .

ترميز الأس

يُشفّر الأسّ الثنائي ذو الدقة المزدوجة باستخدام تمثيل ثنائي الإزاحة ، حيث تكون إزاحة الصفر 1023؛ ويُعرف هذا أيضًا باسم انحياز الأسّ في معيار IEEE 754. ومن أمثلة هذه التمثيلات:

e = = =1:0000000000120011621-1023=2-1022{\displaystyle 2^{1-1023}=2^{-1022}}(أصغر أس للأعداد العادية )
e = = =1023:0111111111123ff1621023-1023=20{\displaystyle 2^{1023-1023}=2^{0}}(إزاحة صفرية)
e = = =1029:1000000010124051621029-1023=26{\displaystyle 2^{1029-1023}=2^{6}}
e = = =2046:1111111111027fe1622046-1023=21023{\displaystyle 2^{2046-1023}=2^{1023}}(أعلى أس)

للأسين معنى خاص:000167ff16

حيث F هو الجزء الكسري من المعامل . جميع أنماط البتات هي ترميز صالح.

باستثناء الاستثناءات المذكورة أعلاه، يتم وصف العدد ذي الدقة المزدوجة بالكامل كما يلي:

(-1)لافتة×2هـ-1023×1.جزء{\displaystyle (-1)^{\text{sign}}\times 2^{e-1023}\times 1.{\text{fraction}}}

في حالة الأعداد دون الطبيعية ( e = 0)، يتم وصف العدد ذي الدقة المزدوجة كما يلي:

(-1)لافتة×21-1023×0.جزء=(-1)لافتة×2-1022×0.جزء{\displaystyle (-1)^{\text{sign}}\times 2^{1-1023}\times 0.{\text{fraction}}=(-1)^{\text{sign}}\times 2^{-1022}\times 0.{\text{fraction}}}

ترتيب الباينيات

على الرغم من أن العديد من المعالجات تستخدم نظام التخزين الصغير (little-endian) لجميع أنواع البيانات (الأعداد الصحيحة، والأعداد العشرية)، إلا أن هناك عددًا من بنى الأجهزة التي تُمثل فيها الأعداد العشرية بنظام التخزين الكبير (big-endian)، بينما تُمثل الأعداد الصحيحة بنظام التخزين الصغير (little-endian). [ 2 ] توجد معالجات ARM تستخدم نظام التخزين المختلط (mixed-endian) للأعداد العشرية ذات الدقة المزدوجة: حيث تُخزن كل كلمة من الكلمتين 32 بت بنظام التخزين الصغير (little-endian)، ولكن تُخزن الكلمة الأكثر أهمية أولًا. أما معالجات VAX ، فتُخزن الكلمات ذات 16 بت بنظام التخزين الصغير (little-endian) بترتيب التخزين الكبير (big-endian). نظرًا لوجود العديد من تنسيقات الأعداد العشرية التي لا يوجد لها تمثيل قياسي على الشبكة، يستخدم معيار XDR معيار IEEE 754 بنظام التخزين الكبير (big-endian). لذلك، قد يبدو غريبًا أن معيار IEEE 754 واسع الانتشار للأعداد العشرية لا يُحدد ترتيب البايتات. [ 3 ] نظريًا، هذا يعني أن بيانات الأعداد العشرية القياسية المكتوبة بواسطة جهاز ما قد لا تكون قابلة للقراءة بواسطة جهاز آخر. مع ذلك، في الحواسيب الحديثة القياسية (أي التي تطبق معيار IEEE 754)، يمكن افتراض أن ترتيب البايتات هو نفسه للأعداد العشرية كما هو للأعداد الصحيحة، مما يجعل التحويل بسيطًا بغض النظر عن نوع البيانات. أما الأنظمة المدمجة الصغيرة التي تستخدم تنسيقات خاصة للأعداد العشرية فقد تكون مسألة أخرى.

أمثلة على الدقة المزدوجة

 0 01111111111 000000000000000000000000000000000000000000000000000 2 ≙ 3FF0 0000 0000 0000 16 ≙ +2 0 × 1 = 1
 0 01111111111 000000000000000000000000000000000000000000000000001 2 ≙ 3FF0 0000 0000 0001 16 ≙ +2 0 × (1 + 2 −52 ) ≈ 1.0000000000000002220 (أصغر عدد أكبر من 1)
 0 01111111111 00000000000000000000000000000000000000000000000010 2 ≙ 3FF0 0000 0000 0002 16 ≙ +2 0 × (1 + 2 −51 ) ≈ 1.0000000000000004441 (ثاني أصغر عدد أكبر من 1)
 0 10000000000 000000000000000000000000000000000000000000000000000 2 ≙ 4000 0000 0000 0000 16 ≙ +2 1 × 1 = 2
 1 10000000000 000000000000000000000000000000000000000000000000000 2 ≙ C000 0000 0000 0000 16 ≙ −2 1 × 1 = −2
 0 10000000000 1000000000000000000000000000000000000000000000000000 2 ≙ 4008 0000 0000 0000 16 ≙ +2 1 × 1.1 2 = 11 2 = 3
 0 10000000001 0000000000000000000000000000000000000000000000000000 2 ≙ 4010 0000 0000 0000 16 ≙ +2 2 × 1 = 100 2 = 4
 0 10000000001 01000000000000000000000000000000000000000000000000000 2 ≙ 4014 0000 0000 0000 16 ≙ +2 2 × 1.01 2 = 101 2 = 5
 0 10000000001 1000000000000000000000000000000000000000000000000000 2 ≙ 4018 0000 0000 0000 16 ≙ +2 2 × 1.1 2 = 110 2 = 6
 0 10000000011 0111000000000000000000000000000000000000000000000000 2 ≙ 4037 0000 0000 0000 16 ≙ +2 4 × 1.0111 2 = 10111 2 = 23
 0 01111111000 10000000000000000000000000000000000000 2 ≙ 3F88 0000 0000 0000 16 ≙ +2 −7 × 1.1 2 = 0.00000011 2 = 0.01171875 (3/256)
 0 00000000000 000000000000000000000000000000000000000000000000001 2 ≙ 0000 0000 0000 0001 16 ≙ +2 −1022 × 2 −52 = 2 −1074 ≈ 4.9406564584124654 × 10 −324 (أصغر عدد موجب دون المستوى الطبيعي)
 0 00000000000 11111111111111111111111111111111111111111111111111111111 2 ≙ 000F FFFF FFFF FFFF 16 ≙ +2 −1022 × (1 − 2 −52 ) ≈ 2.2250738585072009 × 10 −308 (أكبر عدد دون المستوى الطبيعي)
 0 00000000001 00000000000000000000000000000000000000000000000000000 2 ≙ 0010 0000 0000 0000 16 ≙ +2 −1022 × 1 ≈ 2.2250738585072014 × 10 −308 (أصغر عدد طبيعي موجب)
 0 11111111110 1111111111111111111111111111111111111111111111111111111111 2 ≙ 7FEF FFFF FFFF FFFF 16 ≙ +2 1023 × (2 − 2 −52 ) ≈ 1.7976931348623157 × 10 308 (أكبر عدد طبيعي)
 0 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 0000 0000 0000 0000 16 ≙ +0 (صفر موجب)
 1 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 8000 0000 0000 0000 16 ≙ −0 (الصفر السالب)
 0 11111111111 00000000000000000000000000000000000000000000000000 2 ≙ 7FF0 0000 0000 0000 16 ≙ +∞ (ما لا نهاية موجبة)
 1 11111111111 000000000000000000000000000000000000000000000000000 2 ≙ FFF0 0000 0000 0000 16 ≙ −∞ (اللانهاية السالبة)
 0 11111111111 00000000000000000000000000000000000000000000000001 2 ≙ 7FF0 0000 0000 0001 16 ≙ NaN (sNaN على معظم المعالجات، مثل x86 و ARM)
 0 11111111111 100000000000000000000000000000000000000000000000001 2 ≙ 7FF8 0000 0000 0001 16 ≙ NaN (qNaN على معظم المعالجات، مثل x86 و ARM)
 0 11111111111 111111111111111111111111111111111111111111111111111111111 2 ≙ 7FFF FFFF FFFF FFFF 16 ≙ NaN (ترميز بديل لـ NaN)
 0 01111111101 01010101010101010101010101010101010101010101 2 ≙ 3FD5 5555 5555 5555 16 ≙ +2 −2 × (1 + 2 −2 + 2) −4 + ... + 2 −52 ) ≈ 0.3333333333333331483 (أقرب تقريب إلى 1 / 3 )
 0 10000000000 1001001000011111101101010100010001000010110100011000 2 ≙ 4009 21FB 5444 2D18 16 ≈ 3.141592653589793116 (أقرب تقريب لـ π)

لم تُحدد معايير ترميز qNaN وsNaN بشكل كامل في معيار IEEE 754 ، وتعتمد على المعالج. تستخدم معظم المعالجات، مثل معالجات عائلة x86 ومعالجات عائلة ARM ، البت الأكثر أهمية في حقل المعامل للإشارة إلى NaN غير نشط؛ وهذا ما توصي به معايير IEEE 754. أما معالجات PA-RISC فتستخدم هذا البت للإشارة إلى NaN نشط.

بشكل افتراضي، يتم تقريب 1 / 3 إلى الأسفل، بدلاً من الأعلى كما هو الحال في الدقة المفردة ، وذلك بسبب العدد الفردي للبتات في الجزء المهم.

بمزيد من التفصيل:

بالنظر إلى التمثيل الست عشري 3FD5 5555 5555 5555 16 ، الإشارة = 0 الأس = 3FD 16 = 1021 الانحياز الأسي = 1023 (قيمة ثابتة؛ انظر أعلاه) الكسر = 5 5555 5555 5555 16 القيمة = 2 (الأس - انحياز الأس) × 1. الكسر - لاحظ أنه لا يجب تحويل الكسر إلى عدد عشري هنا = 2 −2 × (15 5555 5555 5555 16 × 2 −52 ) = 2 −54 × 15 5555 5555 5555 16 = 0.33333333333333314829616256247390992939472198486328125 ≈ 1/3

سرعة التنفيذ مع الحساب ذي الدقة المزدوجة

عادةً ما يكون استخدام متغيرات الفاصلة العائمة ذات الدقة المزدوجة أبطأ من استخدام نظيراتها ذات الدقة المفردة. ومن المجالات التي تبرز فيها هذه المشكلة بشكل خاص، البرامج المتوازية التي تعمل على وحدات معالجة الرسومات (GPUs). فعلى سبيل المثال، عند استخدام منصة CUDA من Nvidia ، قد تستغرق العمليات الحسابية ذات الدقة المزدوجة، اعتمادًا على مواصفات الجهاز، من ضعفين إلى 32 ضعفًا من الوقت اللازم لإتمامها مقارنةً بالعمليات الحسابية التي تُجرى باستخدام الدقة المفردة . [ 4 ]

بالإضافة إلى ذلك، تحتاج العديد من الدوال الرياضية (مثل sin و cos و atan2 و log و exp و sqrt) إلى المزيد من العمليات الحسابية لإعطاء نتائج دقيقة ذات دقة مزدوجة، وبالتالي فهي أبطأ.

قيود الدقة على القيم الصحيحة

  • يمكن تمثيل الأعداد الصحيحة من 2 53 إلى 2 53 ( − 9,007,199,254,740,992 إلى 9,007,199,254,740,992) بدقة.
  • الأعداد الصحيحة بين 2 53 و 2 54 = 18,014,398,509,481,984 يتم تقريبها إلى مضاعفات العدد 2 (عدد زوجي).
  • الأعداد الصحيحة بين 254 و 255 = 36,028,797,018,963,968 تُقرّب إلى مضاعفات العدد 4.
  • الأعداد الصحيحة بين 2n و 2n + 1 تقرب إلى مضاعفات 2n - 52 .

التطبيقات

تُنفَّذ الأعداد العشرية المزدوجة في العديد من لغات البرمجة بطرق مختلفة. على المعالجات ذات الدقة الديناميكية فقط، مثل معالجات x86 بدون SSE2 (أو عند عدم استخدام SSE2 لأغراض التوافق) والتي تستخدم الدقة الموسعة افتراضيًا، قد تواجه البرامج صعوبات في تلبية بعض المتطلبات.

لغة C ولغة C++

توفر لغتا C و C++ مجموعة واسعة من أنواع البيانات الحسابية . لا تشترط المعايير الدقة المزدوجة (باستثناء الملحق الاختياري F من معيار C99 ، الذي يغطي حسابات IEEE 754)، ولكن في معظم الأنظمة، doubleيتوافق نوع البيانات مع الدقة المزدوجة. مع ذلك، في أنظمة x86 ذات 32 بت مع الدقة الموسعة افتراضيًا، قد لا تتوافق بعض المترجمات مع معيار C، أو قد تعاني العمليات الحسابية من التقريب المزدوج . [ 5 ]

فورتران

توفر لغة فورتران العديد من أنواع الأعداد الصحيحة والحقيقية، ويتوافق نوع 64 بت real64، الذي يمكن الوصول إليه عبر وحدة فورتران المضمنة iso_fortran_env، مع الدقة المزدوجة.

لغة الشفرة الشائعة

توفر لغة Common Lisp أنواع البيانات التالية: SHORT-FLOAT، وSINGLE-FLOAT، وDOUBLE-FLOAT، وLONG-FLOAT. وتُقدم معظم التطبيقات نوعي SINGLE-FLOAT وDOUBLE-FLOAT، مع توفير مرادفات مناسبة للأنواع الأخرى. كما توفر Common Lisp استثناءات لمعالجة حالات تجاوز ونقص البيانات في الأعداد العشرية، بالإضافة إلى استثناء عدم الدقة في الأعداد العشرية، وفقًا لمعيار IEEE 754. لا يتضمن معيار ANSI وصفًا لقيم اللانهاية أو NaN، إلا أن العديد من التطبيقات توفرها كامتدادات.

جافا

في لغة جافا قبل الإصدار 1.2، كان على جميع التطبيقات أن تتوافق مع معيار IEEE 754. سمح الإصدار 1.2 للتطبيقات بإضافة دقة أعلى في العمليات الحسابية الوسيطة لمنصات مثل x87 . ولذلك، تم إدخال مُعدِّل strictfp لفرض حسابات دقيقة وفقًا لمعيار IEEE 754. وقد تم استعادة الدقة العالية للأعداد العشرية في جافا  17. [ 6 ]

جافا سكريبت

كما هو محدد في معيار ECMAScript ، يجب إجراء جميع العمليات الحسابية في جافا سكريبت باستخدام حسابات الفاصلة العائمة ذات الدقة المزدوجة. [ 7 ]

JSON

يدعم تنسيق بيانات JSON القيم العددية، ولا يفرض أي قيود على دقتها أو نطاقها. ومع ذلك، تنصّ RFC 8259 على أنه نظرًا لانتشار استخدام أرقام IEEE 754 الثنائية ذات 64 بت، يمكن لتطبيقات معالجة JSON تحقيق توافقية جيدة إذا لم تتوقع دقة أو نطاقًا أكبر مما توفره الأرقام الثنائية ذات 64 بت. [ 8 ] 

صدأ وزيغ

يحتوي كل من Rust و Zigf64 على نوع البيانات. [ 9 ] [ 10 ]

ملاحظات ومراجع

  1. ويليام كاهان (1 أكتوبر 1997). "ملاحظات محاضرة حول وضع معيار IEEE 754 للحسابات الثنائية ذات الفاصلة العائمة" (ملف PDF) . ص 4. مؤرشف (ملف PDF) من الأصل في 8 فبراير 2012. 
  2. سافارد، جون جي جي (2018) [2005]، "تنسيقات الفاصلة العائمة" ، quadibloc ، مؤرشف من الأصل في 2018-07-03 ، تم استرجاعه في 2018-07-16
  3. "pack – تحويل قائمة إلى تمثيل ثنائي" . مؤرشف من الأصل بتاريخ 18 فبراير 2009. تم الاطلاع عليه بتاريخ 4 فبراير 2009 .
  4. "معالج Titan V الجديد من Nvidia يحقق 110 تيرافلوب من شريحة واحدة" . Tom's Hardware . 2017-12-08 . تم الاطلاع عليه بتاريخ 2018-11-05 .
  5. "الخطأ رقم 323 - الكود المُحسَّن يُعطي نتائج غريبة للأعداد العشرية" . gcc.gnu.org . مؤرشف من الأصل بتاريخ 30 أبريل 2018. تم الاطلاع عليه بتاريخ 30 أبريل 2018 .
  6. دارسي، جوزيف د. "JEP 306: استعادة دلالات الفاصلة العائمة الصارمة دائمًا" . تم الاسترجاع في 12-09-2021 .
  7. مواصفات لغة ECMAScript (ECMA-262 ) (ملف PDF) (الطبعة الخامسة ). إيكما الدولية. ص 29، §8.5 نوع الرقم . مؤرشف (ملف PDF) من الأصل بتاريخ 13-03-2012. 
  8. تي. براي (ديسمبر 2017). تنسيق تبادل البيانات JSON (تدوين كائنات جافا سكريبت) . فريق عمل هندسة الإنترنت . doi : 10.17487/RFC8259 . ISSN 2070-1721 . STD 90. RFC 8259 . معيار الإنترنت 90.
  9. "أنواع البيانات - لغة برمجة Rust" . doc.rust-lang.org . تم الاطلاع عليه بتاريخ 10 أغسطس 2024 .
  10. "الوثائق - لغة برمجة Zig" . ziglang.org . تم الاطلاع عليه بتاريخ 10 أغسطس 2024 .