Я пытаюсь реализовать функцию декремента для десятичных значений в 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()
);
Выше мой код, но он добавляет значения в виде строки



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Обновлено: я только что понял, что запрашивалось только уменьшение. Ну ладно - теперь этот ответ работает и для увеличения ... а также для шагов больше ± 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 (без десятичных знаков), он увеличивается до 101, как и ожидалось, если я ввожу 100,0, он увеличивается до 100,1, если я ввожу 100,00, он увеличивается до 100,01 и т. д.
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, чтобы получить десятичное значение, которое вам нужно.
Если я даю ввод как 100, он увеличивается до 100,9, а при следующем увеличении он изменяется на 101,0. Как сделать его 100,11, и он должен стать 101,0, только если он достигнет 100,99, потому что логически 101,0 возможен только после 100,99. Можете ли вы мне помочь с этим?