петък, 20 февруари 2015 г.

#57 И пак за закръглянето (или как банкерите цепят стотинката):)

И пак за закръглянето... Аман:):):)

     Първо малко теория свързана със закръглянето. Както са ни учили в училище, ако цифрата след знака до който закръгляме е по-голяма или равна на петица я увеличаваме с единица. Т.е. 1.474 закръглено до втория знак е 1.47, а 1.476 е 1.48. В това правило има нещо "нечестно". Цифрите при които НЕ се закръгля са 1,2,3,4, а цифрите при които се закръгля са 5,6,7,8,9. Оказва се, че имаме повече случаи при които се закръгля! Търсят се различни начини за оправяне на тази грешка. Един от тези начини е така нареченото "банкерско закръгляне" (bankers' rounding).  Това е едно от названията на метода: round half to even, unbiased rounding, convergent rounding, statistician's rounding, dutch rounding, gaussian rounding, odd-even rounding, broken rounding. Ето алгоритъма на закръгляне:


  1. Ако следващата цифра след позицията за закръгляне е 0,1,2,3,4, не се извършва промяна на на последния знак: 1.444 си е 1.44. (така са ни учили в училище)
  2. Ако следващата цифра след позицията за закръгляне е 6,7,8,9,  последният знак се увеличава с единица: 1.446 си е 1.45 (така са ни учили в училище).
  3. Ако следващата цифра след позицията за закръгляне е пет и има още цифри след нея, последният знак се увеличава с единица: 1.4451 става 1.45, и 1.4351 става 1.44 (така са ни учили в училище).
  4. Ако следващата цифра след позицията за закръгляне е пет и НЯМА други цифри след нея:
    1. Ако последната цифра е НЕЧЕТНА се извършва увеличение на последния знак. т.е. 1.435 става 1.44 (така са ни учили в училище)
    2. Ако последната цифра е ЧЕТНА,  НЕ СЕ ИЗВЪРШВА увеличение на последния знак. т.е. 1.445 си остава 1.44 (така НЕ СА ни учили в училище:)!!!


    Т.е. да резюмирам разликата между това което сте учили в училището и "банкерското" училище е, ЧЕ АКО СЛЕД ЗНАКА ЗА ЗАКРЪГЛЯНЕ ИМАМЕ ПЕТИЦА (САМО ПЕТИЦА!) И ПОСЛЕДНИЯ ЗНАК Е ЧЕТНО ЧИСЛО НЕ СЕ ИЗВЪРШВА УВЕЛИЧАВАНЕ!

       За повече информация четете тук: Rounding (статия във Wikipedia).

      Защо ви пълня главите с глупости?!:) Искам да ви предпазя от един подводен камък. По-скоро тези от вас, които в даден момент ще започнат да пишат макроси на Visual Basic for Application (VB) . Проблемът се състои в следното: функцията Round в Excel работна книга си работи "нормално". Т.е. тя си закръгля както са ни учили. 1.445 си го закръгля на 1.45! Функцията Round във VBA работи по банкерски!!! За илюстрация съм направил проста потребителска функция (UDF):

Function vbaRound(r As Range, digits As Byte) As Double
   vbaRound = Round(r.Value, digits)
End Function

След което сравних резултата от двете функции:
Сравняване на WorkSheet Round и Round във VBA

      Както се вижда разликата е при четна цифра (4,6...) и ПЕТИЦА без нищо след нея! Обърнете внимание, че ако след петицата има нещо друго, то двете функции си действат по един и същи начин!

     Така, че внимавайте със закръглянията във VBA! Те са различни от закръглянията в работен лист!

    П.П. Ако искате да получите "нормално" закръгляне и във VBA, може да използвате следния запис:Application.WorksheetFunction.Round(......

П.П Ето къде MS са смотали информацията: PRB: Round Function different in VBA 6 and Excel Spreadsheet





Няма коментари:

Публикуване на коментар