Как уменьшить десятичные значения в javascript

Я пытаюсь реализовать функцию декремента для десятичных значений в js.

При нажатии кнопки должно произойти следующее

1.22 -> 1.21
3.00 -> 2.99
1.2345 -> 1.2344

Как я мог это сделать, ниже мой код

var decimals = 1,
    stringC = String(positionData.volume),
    value = parseFloat(positionData.volume);
if (stringC.includes(".")) {
    const splitted = stringC.split(".");
    decimals = splitted[1];
}
const length = decimals?.length;
if (length > 0) {
    decimals = "0.";
    for (let i = 0; i < length; i++) {
        if (i == length - 1) {
            decimals += "1";
        }
        decimals += "0";
    }
}
console.info(decimals);
decimals = parseFloat(decimals).toFixed(2);
setCloseValue((value) =>
    (parseFloat(value) + decimals).toString()
);

Выше мой код, но он добавляет значения в виде строки

Поведение ключевого слова "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
0
55
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Обновлено: я только что понял, что запрашивалось только уменьшение. Ну ладно - теперь этот ответ работает и для увеличения ... а также для шагов больше ± 1.


Я бы решил это следующим образом:

const input = document.getElementById('input')

function applyStep (step) {
  const decimals = input.value.split('.')[1]?.length ?? 0
  const stepSize = 10 ** -decimals
  input.value = (Number(input.value) + stepSize * step).toFixed(decimals)
}

document.getElementById('increment').addEventListener('click', () => applyStep(1))
document.getElementById('decrement').addEventListener('click', () => applyStep(-1))
<input id = "input" value = "1.23" />
<button id = "increment">Inc</button>
<button id = "decrement">Dec</button>

Что я делаю здесь, так это: я сначала проверяю, сколько десятичных знаков у нас есть после . (по умолчанию 0, если точки нет).

Затем я вычисляю размер шага 10-decimals, например. с тремя десятичными знаками мы получаем 10-3, что равно 0,001.

Затем я добавляю заданный шаг (+1 или -1), умноженный на размер шага, к числовому значению и переформатирую его с предыдущим числом десятичных знаков, прежде чем записать его обратно в поле.

Обратите внимание, что это не будет работать с числами, которые выходят за пределы точности типов чисел по умолчанию в JavaScript. Если это желательно, потребуется более сложный подход.

Это можно было бы сделать, обрабатывая целые и дробные части отдельно как два BigInt, но это требует много размышлений, когда речь идет о переносе и отрицательных значениях. Вот возможное решение:

const input = document.getElementById('input')

function applyStep (step) {
  if (!input.value.match(/^-?\d+(\.\d*)?$/)) throw new Error('Invalid format')
  const [strIntegerPart, strFractionalPart = ''] = input.value.split('.')
  let bnIntegerPart = BigInt(strIntegerPart)
  let bnFractionalPart = BigInt(strFractionalPart)
  const decimals = strFractionalPart.length
  const maxFractionalPart = 10n ** BigInt(decimals)
  let negative = strIntegerPart.startsWith('-') && (bnIntegerPart || bnFractionalPart)
  
  if (negative) {
    bnIntegerPart *= -1n
    step *= -1n
  }
  
  bnFractionalPart += step
  const offset = bnFractionalPart < 0n ? maxFractionalPart - 1n : 0n
  const carry = (bnFractionalPart - offset) / maxFractionalPart
  bnIntegerPart += carry
  bnFractionalPart -= carry * maxFractionalPart
  
  if (bnIntegerPart < 0n) {
    if (bnFractionalPart) {
      bnIntegerPart += 1n
      bnFractionalPart = maxFractionalPart - bnFractionalPart
    }
    bnIntegerPart *= -1n
    negative = !negative
  }
  
  let newValue = bnIntegerPart.toString()
  if (decimals > 0) newValue += '.' + bnFractionalPart.toString().padStart(decimals, '0')
  if (negative && (bnIntegerPart || bnFractionalPart)) newValue = '-' + newValue
  
  input.value = newValue
}

document.getElementById('increment').addEventListener('click', () => applyStep(1n))
document.getElementById('decrement').addEventListener('click', () => applyStep(-1n))
<input id = "input" value = "1.23" />
<button id = "increment">Inc</button>
<button id = "decrement">Dec</button>

Оба этих решения будут работать и с шагами, отличными от 1 и -1.

Если я даю ввод как 100, он увеличивается до 100,9, а при следующем увеличении он изменяется на 101,0. Как сделать его 100,11, и он должен стать 101,0, только если он достигнет 100,99, потому что логически 101,0 возможен только после 100,99. Можете ли вы мне помочь с этим?

Lahfir 18.10.2022 22:05

Я не понимаю - я пробовал оба примера, и если я ввожу 100 (без десятичных знаков), он увеличивается до 101, как и ожидалось, если я ввожу 100,0, он увеличивается до 100,1, если я ввожу 100,00, он увеличивается до 100,01 и т. д.

CherryDT 18.10.2022 23:39

const decrementVarable = (decimal)=>{
  let decToString = decimal.toString().split('.')
  if (decToString.length > 1){
    let value = decToString[1]
    let number = Number('1'+ '0'.repeat(value.length))
    let numWithoutDecimal = ((decimal * number)-1)/number
    return numWithoutDecimal
  }

  return (decimal-1);
}

используйте этот код, просто передайте свое десятичное число

Плавающие точки обычно беспорядочны. Если вам действительно нужна точность на 100%, используйте целочисленную переменную, увеличивайте ее на 1 на каждой итерации, проверяйте, когда она достигает 100, а затем, для фактического расчета, возьмите свою переменную и разделите ее на 100, чтобы получить десятичное значение, которое вам нужно.

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