كيف يمكنني الحفاظ على الوقت دون التراكمي الخطأ ؟

StackOverflow https://stackoverflow.com/questions/1654661

  •  11-09-2019
  •  | 
  •  

سؤال

كيف يمكنك الحفاظ على المسار من الوقت بطريقة بسيطة جزءا لا يتجزأ من النظام ، بالنظر إلى أن كنت في حاجة الى نقطة ثابتة التمثيل من خلال هذا الوقت بين القراد ليس بالضبط expressable في تلك النقطة الثابتة تنسيق ؟ كيف يمكنك تجنب الأخطاء التراكمية في تلك الظروف.

هذا السؤال هو رد فعل هذه المادة على سمبي.

0.1 ثانية لا يمكن بدقة عن الثنائية النقطة الثابتة رقم ، كما 1/3 لا يمكن بدقة كنسبة عشري النقطة الثابتة رقم.أي ثنائي التمثيل نقطة ثابتة لديه خطأ صغير.على سبيل المثال, إذا كان هناك 8 بت الثنائية بعد نقطة (أي باستخدام قيمة عدد صحيح تحجيم 256), 0.1 مرات 256 هو 25.6 التي سيتم تقريب إما 25 أو 26, مما أدى إلى خطأ في ترتيب -2.3% أو +1.6% على التوالي.إضافة المزيد من بت الثنائية بعد نقطة يقلل من حجم هذا الخطأ ولكن لا يمكن القضاء عليه.

مع تكرار ذلك الخطأ يتراكم تدريجيا.

كيف يمكن تجنب ذلك ؟

هل كانت مفيدة؟

المحلول

نهج واحد ليس في محاولة لحساب الوقت من خلال إضافة متكررة لهذا الثانية 0.1 ثانية، ولكن للحفاظ على عدد صحيح على مدار الساعة عددا صحيحا. يمكن تحويل عدد القراد هذا إلى وقت محدد في ثوان حسب الحاجة، عادة ما يستخدم الضرب بعد التقسيم. بالنظر إلى أجزاء كافية في التمثيل الوسيط، فإن هذا النهج يسمح بأي تحجيم عقلاني، ولا تتراكم الأخطاء.

على سبيل المثال، إذا كان عدد القراد الحالي 1024، فيمكننا الحصول على الوقت الحالي (في النقطة الثابتة مع 8 بت بعد النقطة) بضرب ذلك بنسبة 256، ثم تقسيم بنسبة 10 - أو معادل، بضربه بحلول عام 128 ثم تقسيمه بواسطة 5 . وفي كلتا الحالتين، هناك خطأ (الباقي في التقسيم)، ولكن يحد الخطأ لأن الباقي هو دائما أقل من 5. لا يوجد خطأ تراكمي.

نصائح أخرى

قد يكون نهج آخر مفيدا في سياقات حيث يعتبر الضرب والقسمة عدد صحيحا مكلفا للغاية (والتي يجب أن تكون نادرة جدا في هذه الأيام). انه يحتصر فكرة من خوارزمية رسم خط بريسنهامز. وبعد يمكنك الاحتفاظ بالوقت الحالي في نقطة ثابتة (بدلا من عدد القراد)، ولكن يمكنك أيضا الاحتفاظ بمصطلح الخطأ. عندما ينمو مصطلح الخطأ كبيرا جدا، يمكنك تطبيق تصحيح في القيمة الزمنية، وبالتالي منع الخطأ من التراكم.

في مثال 8 بت بعد نقطة، فإن تمثيل 0.1 ثانية هو 25 (256/10) مع مصطلح خطأ (باقي) 6. في كل خطوة، نضيف 6 إلى تراكم خطأ لدينا. بناء على هذا حتى الآن، فإن الخطوتين الأولين ...

Clock  Seconds  Error
-----  -------  -----
 25    0.0977    6
 50    0.1953   12

في الخطوة الثانية، تجاوزت قيمة الخطأ - تجاوزت 10. لذلك، نحن زيادة الساعة وطرح 10 من الخطأ. يحدث هذا في كل مرة تصل فيها قيمة الخطأ إلى 10 أو أعلى.

لذلك، التسلسل الفعلي هو ...

Clock  Seconds  Error  Overflowed?
-----  -------  -----  -----------
 25    0.0977    6
 51    0.1992    2      Yes
 76    0.2969    8
102    0.3984    4      Yes

هناك دائما خطأ تقريبا (تكون الساعة صحيحة بدقة فقط عندما تكون قيمة الخطأ صفرية)، لكن الخطأ يحدها ثابتا صغيرا. لا يوجد خطأ تراكمي في قيمة الساعة.

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

هذا يعمل فقط إذا كان هناك تنسيق واحد فقط نقطة ثابتة يستخدم للساعة.

لماذا لا يكون لديك مضادة 0.1 ثانية وزيادة كل عشر مرات عداد ثواني الخاص بك، وينفذ 0.1 العداد مرة أخرى إلى 0؟

في هذه الحالة بالذات، كنت قد أبقى ببساطة العد الوقت في أعشار ثوان (أو مللي ثانية، أو أي نطاق الوقت المناسب للتطبيق). أفعل هذا طوال الوقت في أنظمة صغيرة أو أنظمة التحكم.

لذلك سيتم تخزين قيمة الوقت 100 ساعة 3_600_000 القراد - خطأ صفر (بخلاف الخطأ الذي قد يتم تقديمه بواسطة الأجهزة).

المشاكل التي يتم تقديمها بواسطة هذه التقنية البسيطة هي:

  • تحتاج إلى حساب الأرقام الأكبر. على سبيل المثال، قد تضطر إلى استخدام عداد 64 بت بدلا من عداد 32 بت
  • جميع حساباتك تحتاج إلى أن تكون على دراية بالوحدات المستخدمة - هذه هي المنطقة الأكثر احتمالا في أن تسبب مشاكل. أحاول المساعدة في هذه المشكلة باستخدام عدادات الوقت مع وحدة موحدة. على سبيل المثال، يحتاج هذا المضادة المعينة إلى 10 علامات فقط في الثانية، ولكن قد يحتاج عداد آخر إلى دقة millisecond. في هذه الحالة، كنت أفكر في جعل كلا العدادين مللي ثانية بدقة حتى يستخدمون نفس الوحدات على الرغم من أن المرء لا يحتاج حقا إلى هذا الدقة.

لقد اضطررت أيضا إلى لعب بعض الحيل الأخرى بهذا مع أجهزة ضبط الوقت التي ليست "منتظمة". على سبيل المثال، عملت على جهاز يطلب من اكتساب البيانات تحدث 300 مرة ثانية. توقيت الأجهزة أطلقت مرة واحدة مللي ثانية. لا توجد طريقة لتوسيع نطاق الموقت الميلي ثانية للحصول على 1/300 بالضبط من الوحدات الثانية. لذلك كان علينا أن نواجه المنطق الذي من شأنه إجراء عملية الاستحواذ على البيانات على كل 3 و 3 و 4 علاقات للحفاظ على الاستحواذ من الانجراف.

إذا كنت بحاجة إلى التعامل مع خطأ وقت الأجهزة، فأنت بحاجة إلى أكثر من مصدر وقت واحد واستخدامها معا للحفاظ على الوقت الكلي في المزامنة. اعتمادا على احتياجاتك، يمكن أن يكون هذا مجمعا بسيطا أو رائعا.

شيء رأيت نفذت في الماضي:زيادة قيمة لا يمكن التعبير عنها بدقة في نقطة ثابتة الشكل ، ولكن فإنه يمكن التعبير عن الكسر.(هذا هو مماثل إلى "الحفاظ على المسار من قيمة خطأ" الحل.)

في الواقع في هذه الحالة المشكلة كانت مختلفة قليلا ، ولكن من الناحية النظرية مماثلة—المشكلة لم يكن التمثيل نقطة ثابتة على هذا النحو ، ولكن اشتقاق الموقت من الساعة المصدر أنه لم يكن متعددة.لدينا الأجهزة على مدار الساعة القراد في 32,768 هرتز (مشتركة مشاهدة كريستال على أساس الطاقة المنخفضة الموقت).أردنا ميلي ثانية واحدة الموقت من ذلك.

ميلي ثانية واحدة الموقت يجب أن الزيادة كل 32.768 الأجهزة القراد.تقريب الأول هو زيادة كل 33 الأجهزة القراد ، الاسمية 0.7% خطأ.ولكن, مشيرا إلى أن 0.768 هو 768/1000 ، أو 96/125 ، يمكنك القيام بذلك:

  • نضع متغير على "كسرى" قيمة.نبدأ على 0.
  • انتظر الأجهزة الموقت العد 32.
  • بينما الصحيح:
    • زيادة ميلي ثانية واحدة الموقت.
    • إضافة 96 إلى "كسرى" قيمة.
    • إذا كان "كسرى" القيمة >= 125, طرح 125 من ذلك وانتظر الأجهزة الموقت العد 33.
    • (وإلا فإن "كسرى" القيمة < 125) ، انتظر الأجهزة الموقت العد 32.

سوف يكون هناك بعض المدى القصير "غضب" على ميلي ثانية واحدة العداد (32 مقابل 33 الأجهزة القراد) ولكن على المدى الطويل متوسط سوف يكون 32.768 الأجهزة القراد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top