JavaScript | Как умножать дробные на целые?

JavaScript | Как умножать дробные на целые?

Этого вопроса никогда бы не появилось, если бы не двоичная система счисления, которая подливает проблем при умножении дробных чисел на целые в JavaScript.

Пример проблемы умножения:

0.15 * 6

Результат вычисления:

0.8999999999999999

Ещё пример:

1.11 * 7
7.7700000000000005
Проблема умножения дробного на целое - JavaScript
Проблема умножения дробного на целое — JavaScript

Очевидно это какой-то бред, потому что (0.15 * 6) = 0.9; а 1.11 * 7 = 7.77

 

Как работать с подобной неточностью вычислений?

Функция для правильного умножения дробного числа на целое число

Для правильного умножения дробного на целое предлагаю написать свою функцию, которая по сути будет менять знак умножения «*» на знак сложения «+»

function fractional_multiplication (a, b) {
   var arr = [];
   function sum (x){ var s = 0; for (i = 0; i < x.length; i++){ s += x[i] } return s };
   if (Number.isInteger(a) == true){ arr.length = a; arr.fill(b); return sum(arr) }
   else {arr.length = b; arr.fill(a); return sum(arr)}
}

Как работает эта функция?

Она получает на вход два параметра — два числа. Предполагается, что одно число будет дробным, а другое целым. Функция универсальна и можно подавать числа в любом порядке т. к. проверяется условие — является ли число целым.

В теле функции создаётся переменная arr, которая является пустым массивом. Переменная arr замкнута в функции fractional_multiplication() из-за области видимости. Снаружи к ней нет доступа и она создаётся только в момент вычисления. После вычисления переменная arr удаляется из оперативной памяти.

Переменная arr нужна нам для того, чтобы заполнить массив нужным количеством элементов с дробными числами. Для этого используется «заливка» метод fill() для объектов-прототипов Array. Пример массива arr, [0.15, 0.15, 0.15, 0.15, 0.15, 0.15]. Длина массива будет взята из целого числа.

После создания массива из одинаковых дробных чисел нам нужно будет просуммировать их между собой. С этой задачей справится функция sum(), которая принимает массив из чисел, и возвращает сумму значений элементов.

 

Результат работы функции

fractional_multiplication(0.15, 6)
0.9
fractional_multiplication(6, 0.15)
0.9

Вывод в консоль:

Функция для правильного умножения дробного на целое - JavaScript
Функция для правильного умножения дробного на целое — JavaScript

 

Альтернативный способ для умножения

Можно производить округления до определённого знака методом toFixed(). Он вернёт строку, которую потом можно преобразовать в число при помощи конструктора Number().

Number((0.15 * 6).toFixed(10))
0.9

Number((1.11 * 7).toFixed(10))
7.77
Округление неточности вычислений до 10 знака - JavaScript
Округление неточности вычислений до 10 знака — JavaScript
(0.15 * 6).toFixed(10)
"0.9000000000"

(1.11 * 7).toFixed(10)
"7.7700000000"
Пример округления до 10 знака после точки - JavaScript
Пример округления до 10 знака после точки — JavaScript

 

Информационные ссылки

JavaScript | Как сложить все числа в массиве?

Официальная страница стандарта ECMAScripthttps://tc39.es/ecma262/

Официальная страница стандарта ECMAScript — Раздел «20.1 Number Objects» — https://tc39.es/ecma262/#sec-number-objects

Официальная страница стандарта ECMAScript — Раздел «20.1.2.3 Number.isInteger ( number )» — https://tc39.es/ecma262/#sec-number.isinteger

Официальная страница стандарта ECMAScript — Раздел «22.1.3.6 Array.prototype.fill ( value [ , start [ , end ] ] )» — https://tc39.es/ecma262/#sec-array.prototype.fill