كل كو
الملتحي ، الرفاق!
نعلم جميعا ما هو التقريب. إذا نسي شخص ما ، فسيكون التقريب هو استبدال الرقم بقيمة تقريبية ، مكتوبًا بأرقام أقل أهمية. إذا سألت أي شخص على الطاير عما يحدث عندما تقوم بالدوران 6.5 إلى الأعداد الصحيحة ، فسوف يجيب على "7" دون تردد. لقد تعلمنا من المدرسة أن الأرقام يتم تقريبها إلى أقرب عدد صحيح ، وهو أكبر من حيث القيمة المطلقة. أي إذا كان العدد الكسري في العدد المستدير يساوي أو يزيد عن نصف التفريغ للجزء بالكامل ، فإننا نجمع الرقم الأصلي إلى أقرب رقم أكبر.
ببساطة:
6,4 = 6 6,5 = 7 6,6 = 7
إلخ
وهكذا ، مع ترك المدرسة وتصبح مبرمجًا ، نتوقع غالبًا نفس السلوك من لغات البرمجة القوية لدينا. ننسى تمامًا أننا في المدرسة تعلمنا "التقريب الرياضي" ، ولكن في الواقع هناك أنواع أكثر بكثير من التقريب. في ويكيبيديا وحدها ،
يمكنك حفر عدد خيارات التقريب 0.5 إلى أقرب عدد صحيح:
- التقريب الرياضي
- التقريب عشوائي
- بالتناوب التقريب
- تقريب البنك
النوع الأول ، "التقريب الرياضي" ، تعلمنا جميعًا من المدرسة. يمكنك أن تقرأ عن النوعين الثاني والثالث في وقت فراغك ، فهي ليست مثيرة للاهتمام بالنسبة لي في هذا المقال اليوم.
لكن "التقريب المصرفي" مثير للاهتمام بالفعل. "لماذا؟" - أنت تسأل. في الشبكة الفرعية ، غالبًا ما نستخدم فئة
تحويل ، والتي توفر الكثير من الطرق لتحويل نوع بيانات واحد إلى آخر (يجب عدم الخلط بينه وبين طاقم العمل ، سيتم وصفه أدناه). والآن ، اتضح أنه عند تحويل أرقام
الفاصلة العائمة (
مزدوجة ، عائمة ، عشرية ) إلى نوع صحيح
صحيح من خلال أسلوب
Convert.ToInt32 ، يعمل التقريب "المصرفي" تحت الغطاء. يتم استخدامه هنا افتراضيا!
ويبدو أن جهل هذا تافه لا يؤثر بشكل كبير على عملك ، ولكن بمجرد أن تضطر إلى العمل مع الإحصاءات وحساب المؤشرات على أساس مجموعة من جميع أنواع السجلات والأرقام ، سيظهر هذا الشيء في اتجاه جانبي. لأننا نتوقع (من الجهل) أن تعمل جميع التحويلات / التقريب في الحسابات وفقًا لقواعد التقريب "الرياضي". ونبدو مثل كبش على بوابة جديدة نتيجة التقريب
6.5 ، وهو
6 .
الفكرة الأولى للمبرمج الذي يرى ذلك هي: "ربما يكون التقريب يعمل في الاتجاه المعاكس ، ووفقًا للقواعد التي يتم تقريبها إلى أقل عدد؟" ، "ربما نسيت شيئًا من الرياضيات المدرسية؟". ثم يذهب إلى google ويفهم أنهم لم ينسوا شيئًا ما ، وأن هناك نوعًا من الغوغاء يجري. في هذه الخطوة ، سيقرر المطور البطيء أن هذا هو السلوك القياسي لأسلوب
Convert.ToInt32 ، ثم
التقريب إلى أصغر عدد صحيح ، والنتيجة لمزيد من البحث. وسوف يعتقد أنه إذا
Convert.ToInt32 (6،5) =
6 ، ثم عن طريق القياس
Convert.ToInt32 (7،5) =
7 . ولكن كان هناك. في المستقبل ، سيتم ضرب هؤلاء المطورين على رأسهم مع مجموعة من الأخطاء من قسم ضمان الجودة.
والحقيقة هي أن التقريب "المصرفي" يعمل بشكل أصعب بعض الشيء - فهو يقرب رقمًا إلى أقرب عدد صحيح ، وليس إلى أقرب عدد صحيح. من المفترض أن هذا النوع من التقريب أكثر صدقًا في حالة التطبيق في العمليات المصرفية - لن تحرم البنوك نفسها أو العملاء ، على افتراض أن هناك عددًا كبيرًا من العمليات مع جزء صحيح أكبر مثل العمليات التي بها جزء صحيح فردي. ولكن بالنسبة لي - لا يزال غير واضح :) ولهذا السبب ستعطي
Convert.ToInt32 (6.5) نتيجة
6 ، وستكون نتيجة
Convert.ToInt32 (7.5) 8 ، وليس 7 :)
ما يجب القيام به للحصول على التقريب "الرياضي" للجميع؟ لا تحتوي أساليب
تحويل الفئة على خيارات تقريب إضافية. هذا صحيح ، لأن هذا الفصل لا يخدم في المقام الأول في التقريب ، ولكن لتحويل النوع. تأتي فئة
الرياضيات الرائعة
بأسلوبها الدائري في عملية الإنقاذ. لكن عليك أيضًا توخي الحذر ، لأن هذا الأسلوب يعمل افتراضيًا مثل التقريب في
Convert.ToInt32 () - وفقًا للقاعدة "المصرفية". ومع ذلك ، يمكن تغيير هذا السلوك باستخدام الوسيطة الثانية ، والتي تعد جزءًا من أسلوب
Round . لذلك ،
Math.Round (someNumber ، MidpointRounding.ToEven ) سيعطينا التقريب الافتراضي "المصرفي". لكن
Math.Round (someNumber ، MidpointRounding.AwayFromZero ) ستعمل وفقًا للقواعد المعتادة للتقريب "الرياضي".
وبالمناسبة ، لا يستخدم
Convert.ToInt32 () System.Math.Round () تحت الغطاء. حفر الحفر بشكل خاص
لتنفيذ هذه الطريقة على جيثب - التقريب يعتبر وفقا للالمتبقيات:
public static int ToInt32(double value) { if (value >= 0) { if (value < 2147483647.5) { int result = (int)value; double dif = value - result; if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++; return result; } } else { if (value >= -2147483648.5) { int result = (int)value; double dif = value - result; if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--; return result; } } throw new OverflowException(Environment.GetResourceString("Overflow_Int32")); }
وأخيرًا ، بضع كلمات حول
نوع الكتابة :
var number = 6.9; var intNumber = (int)number;
في هذا المثال ، قمت بإلقاء نوع نقطة عائمة (
مضاعفة في هذه الحالة) على عدد صحيح
int . لذلك ، عند الاختيار إلى أنواع عدد صحيح ، يتم
اقتطاع الجزء غير الصحيح بأكمله. وفقًا لذلك ، في هذا المثال ،
سيحتوي المتغير "
intNumber "
على الرقم
6 . لا توجد قواعد التقريب هنا ، فقط قطع كل ما يأتي بعد العلامة العشرية. تذكر هذا!
روابط ذات صلة:
ملاحظة: بفضل مكسيم Yakushkin لجذب الانتباه إلى هذه اللحظة الضمنية.
PPS بالمناسبة ، في
بيثون ، التقريب الافتراضي يعمل بنفس الطريقة على أساس "مصرفي". ربما نفس الشيء في لغتك ، كن حذرا مع الأرقام :)