Деление числа Javascript

У меня есть несколько случаев, которые мне нужно охватить при делении чисел.

ПРАВИЛА: - Деление всегда должно возвращать 2 знака после запятой - Не должно быть округления.

Это логика, которую я использую:

function divideAndReturn (totalPrice, runningTime) {
  let result;
  let totalPriceFloat = parseFloat(totalPrice).toFixed(2);
  let runningTimeNumber = parseInt(runningTime, 10); // Always a round number
  result = totalPriceFloat / runningTimeNumber; // I do not need rounding. Need exact decimals

  return result.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]; // Preserve only two decimals, avoiding rounding up.
}

Он работает, как и ожидалось, для следующего случая:

let totalPrice = '1000.00';
let runningTime = '6';
// result is 166.66

Это также работает для этого случая:

let totalPrice = '100.00';
let runningTime = '12';
// Returns 8.33

Но для этого случая это не работает должным образом:

let totalPrice = '1000.00';
let runningTime = '5';
// Returns 200. Expected is 200.00

Кажется, когда я делю круглые числа, само деление удаляет десятичные знаки .00

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

PS. Числа поступают из базы данных и всегда изначально являются строками.

Ваша переменная totalPriceFloat является строкой, а не числом. toFixed() возвращает строку, представляющую заданное число, используя нотацию с фиксированной точкой.

Weedoze 03.05.2019 09:16

Ты прав. Но как я мог получить «1000,00» для анализа и стать 1000,00?

Wexoni 03.05.2019 09:52

Я не уверен, что вы подразумеваете под отсутствием округления! Удаляя «завершающие» десятичные цифры, вы округляете число в меньшую сторону. Пожалуйста, объясните, почему вы хотите такого поведения.

phuzi 03.05.2019 10:40
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
118
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете попробовать добавить toFixed(2) в строку результата:

result = (totalPriceFloat / runningTimeNumber).toFixed(2);

Мне не нужно округление.

Wexoni 03.05.2019 10:38

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

Почему бы вам не проанализировать 2 входа как числа, сделать деление, а затем отформатировать вывод, чтобы он соответствовал тому, что вам нужно?

function divideAndReturn (totalPrice, runningTime) {
    let result;
    let totalPriceFloat = parseFloat(totalPrice); // no need to format anything right now
    let runningTimeNumber = parseInt(runningTime, 10); // Always a round number
    result = totalPriceFloat / runningTimeNumber; // I do not need rounding. Need exact decimals

    return result.toFixed(2) // returns a string with 2 digits after comma
}

Если я вызываю toFixed(), то он округляется. Мне нужны точные результаты, без округлений.

Wexoni 03.05.2019 10:14

Тогда я не уверен, что понимаю. Вы хотите сохранить по крайней мере 2 десятичных знака? или вы хотите сохранить ровно 2 десятичных знака, но без округления?

Gruntzy 03.05.2019 10:20

Я всегда хочу сохранить два десятичных знака без округления.

Wexoni 03.05.2019 10:21

как насчет чего-то вроде return (Math.floor(100 * result)/100) тогда?

Gruntzy 03.05.2019 10:27
Ответ принят как подходящий

Рекомендуемая стратегия состоит в том, чтобы сначала умножить число на 100 (если вам требуется 3 цифры после запятой, затем 1000 и т. д.). Преобразуйте результат в целое число, а затем разделите на 100.

function divideAndReturn (totalPrice, runningTime) {
    let result;
    let totalPriceFloat = parseFloat(totalPrice); // no need to format anything right now
    let runningTimeNumber = parseInt(runningTime, 10); // Always a round number
    result = parseInt((totalPriceFloat * 100) / runningTimeNumber); // I do not need rounding. Need exact decimals
    result /= 100
    return result.toFixed(2) // returns a string with 2 digits after comma
}

console.info(divideAndReturn('1000.00', 6))
console.info(divideAndReturn('100.00', 12))
console.info(divideAndReturn('1000.00', 5))

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

function divideAndReturn (totalPrice, runningTime) {
  let totalPriceFloat = parseFloat(totalPrice);
  let runningTimeNumber = parseInt(runningTime, 10);
  let result = totalPriceFloat / runningTimeNumber;
  
  // without rounding result
  let ret = result.toFixed(3)
  return ret.substr(0, ret.length-1);
}

console.info(divideAndReturn('1000.00', '6'))
console.info(divideAndReturn('100.00', '12'))
console.info(divideAndReturn('1000.00', '5'))

Чтобы удалить любое «округление», используйте toFixed(3) и отбросьте последнюю цифру.

Первый расчет округляется, чего я хочу избежать. Он возвращает 166,67 вместо 166,66. Однако последний теперь отображается правильно.

Wexoni 03.05.2019 10:37

@vedran, пожалуйста, объясните, что не так с ответом, чтобы я мог понять проблему, а не редактировать свою

phuzi 03.05.2019 10:37

Я обновил вопрос с точным требованием. Спасибо, что уделили время.

Wexoni 03.05.2019 10:38

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

phuzi 03.05.2019 10:38

Я согласен, но это требования, которым я должен следовать.

Wexoni 03.05.2019 10:39

@VedranMaricevic Удовлетворяет ли обновление вашим требованиям?

phuzi 03.05.2019 10:43

Да, это так. Я проголосовал за ваш ответ. У меня было два возможных ответа, один путем умножения на 100 и ваш ответ. Оба дают одинаковые результаты. Я выбрал "умножение"

Wexoni 03.05.2019 10:49

Другие вопросы по теме