Рубрики
Без рубрики

Почему округление важнее, чем думаешь

О авторе и эти заметки За последние три года я работал в Fintech Companies, а я … помечен с деньгами, JavaScript, округлением, денежным.

О авторе и Эти ноты

За последние три года я работал в Fintech Companies, и я часто вижу, что разработчики JavaScript пытаются использовать только цифры или строки (например, https://github.com/mikemcl/bignumber.js ) с денежными ценностями. Я думаю, что это неправильный путь, а строки или цифры не очень хорошо подходят для финансовых приложений. Но кто-то, вероятно, может спросить, почему? В серии статей я попытаюсь описать почему.

Введение

Округление – очень простой, но глубокий вопрос. Что js приносит нам, когда мы говорим о математических операциях? Да, у нас есть математический объект, который приносит нам методы круглых ценностей.

Math.round(5.5)
// => 6

Math.trunc(5.5)
// => 5

Math.floor(5.5)
// => 5

Math.ceil(5.5)
// => 6

Но в чем проблема? Ну, когда мы говорим о округле, мы говорим о преобразовании некоторого количества из большей точности до меньшей точности.

Например, у вас есть функция, которая заканчивается ценностью доллара, такое как $ 7.112312, поэтому ценность округления с центами составит 7,11 доллара, что менее точно.

Итак, когда мы раунд, мы хотим, чтобы наш алгоритм минимизировать влияние потерянных ценностей (например, наших центов).

Вы можете сказать: «Это совсем не важно, это всего лишь 1 цент. Ты шутишь, что ли?” ; Ну, для тех, кто не заинтересован в деталях, просто проверьте https://github.com/frolovdev/easymoney Отказ

Для других, кто заинтересовал, не на самом деле, дай мне сек

Какое влияние может округлить?

Предположим, вы являетесь инвестором – действительно большой инвестор, другими словами, менеджер по хедж-фонду, и вы решите вложить свои $ 200, покупая некоторые акции. В нашей модели цена акций зависит только от одного принципа: чем больше людей, которые хотят купить акции, тем больше цена (цена) акции имеют и наоборот.

Двигаясь, мы притворяемся, что цена на акции колеблется каждую секунду со случайными значениями от -0,05 до +0,05 (вы покупаете и продаете).

Давайте рассмотрим немного кода. Вы не хотите думать о округлении и решили отрезать все после третьего десятилетнего времени. В математике это называется усеченным или округлением к нулю, но Math.trunch в JS не дает нам возможность решить, сколько мы хотим, поэтому я создал реализацию ручной работы с 3 десятиками.

function truncate(n) {
  return parseInt(n * 1000, 10) / 1000;
}

Просто сдвигая десятичную точку на три места вправо при умножении на 1000, мы получаем целочисленную часть для результата. И сдвиг десятичную точку три места, оставленные при разделении на 1000.

Следующий шаг, принесите наши два экспериментальных значения, один для отслеживания фактического значения ваших акций после завершения симуляции, а другой для значения ваших акций после того, как вы усечали до трех десятичных знаков на каждом шаге.

let actualValue = 200;
let truncatedValue = 200;

Теперь создайте нашу модель и займите 100000 секунд. Это около 1,5 дня. За каждую секунду генерируйте случайное значение от -0,05 до 0,05, а затем обновите фактическое значение и усеченное значение.

function truncate(n) {
  return parseInt(n * 1000, 10) / 1000;
}

let actualValue = 200;
let truncatedValue = 200;

// just generate random value between -0.05 and +0.05
function generateNumber() {
  return Number((Math.random() * (0.05 + 0.05) - 0.05).toFixed(10));
}

//  make 1000000 operations in for loop
for (let i = 0; i < 1000000; i++) {
  // rand fluctuation
  const randFluctuation = generateNumber();

  // real value after buy or sell
  actualValue = actualValue + randFluctuation;

  // truncated value
  truncatedValue = truncate(truncatedValue + randFluctuation);
}

// log resulted values
console.log(actualValue);
console.log(truncatedValue);

Вот мой пример (вы можете запустить симуляцию в вашем браузере и получить свои собственные результаты).

Работа с реальными ценностями, вы зарабатываете 13 долларов, но с усечением вы обанкротились!

Давайте повторно запустим симуляцию, но с математическим округлением.

// round implementation

(function() {

  function decimalAdjust(type, value, exp) {
    if (typeof exp === 'undefined' || +exp === 0) {
      return Math[type](value);
    }
    value = +value;
    exp = +exp;

    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
      return NaN;
    }

    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));

    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
  }


  if (!Math.round10) {
    Math.round10 = function(value, exp) {
      return decimalAdjust('round', value, exp);
    };
  }

  if (!Math.floor10) {
    Math.floor10 = function(value, exp) {
      return decimalAdjust('floor', value, exp);
    };
  }

  if (!Math.ceil10) {
    Math.ceil10 = function(value, exp) {
      return decimalAdjust('ceil', value, exp);
    };
  }
})();

let actualValue = 200;
let truncatedValue = 200;

function generateNumber() {
  return Number((Math.random() * (0.05 + 0.05) - 0.05).toFixed(10));
}

for (let i = 0; i < 1000000; i++) {
  const randFluctuation = generateNumber();
  actualValue = actualValue + randFluctuation;

  truncatedValue = Math.round10(truncatedValue + randFluctuation, -4);
}

console.log(actualValue);
console.log(truncatedValue);

Теперь все становится лучше, но мы теряем центы. И это также может быть проблемой. Мы описываем, как справиться с этой проблемой в последующих главах.

Вы также можете прочитать о Ванкувер фондовая биржа которые уселили общее значение показателя до трех десятичных знаков вместо округления. Ошибки округления даже привели к потере жизни: http://www-users.math.umn.edu/~arnold/disasters/patriot.html.

Нижняя линия является округлением важно, а застройщики несут ответственность за то, что являются общими вопросами и как с ними разобраться. В следующей главе мы пытаемся глубоко погружаться в различные алгоритмы округления и выяснить различия между ними.

Не стесняйтесь задавать вопросы, чтобы выразить любое мнение и обсудить с вашей точки зрения. Поделиться, подписаться и сделать код, а не войну. ❤ ️

Оригинал: “https://dev.to/frolovdev/why-rounding-is-more-important-than-you-think-134j”