Я работаю над проектом, и мне нужно реализовать функцию magic_inc, которая увеличивает или уменьшает заданное значение на основе определенной логики. Цель этой функции — применить пользовательскую последовательность увеличения или уменьшения к входному значению. Вот последовательность:
Для увеличения (режим «inc»):
0.5 > 0.6 > 0.7 > 0.8 > 0.9 > 1 > 2 > 3 > 4 > 5 > 6 > 7 > 8 > 9 > 10 > 20 > 30 > 40 > 50 > 60 > 70 > 80 > 90 > 100 > 200 > 300 > 400 > etc.
Для декремента (режим 'dec'):
0.5 > 0.4 > 0.3 > 0.2 > 0.1 > 0.09 > 0.08 > 0.07 > 0.06 > 0.05 > 0.04 > 0.03 > 0.02 > 0.01 > 0.009 > 0.008 > 0.007 > 0.006 > 0.005 > etc.
Функция также должна обрабатывать отрицательные значения. Например, для режима «вкл.»:
inc : -0.3 > -0.2 > -0.1 > -0.09 > -0.08 > -0.07 > etc.
и для режима «dec»:
dec : -0.7 > -0.8 > -0.9 > -1 > -2 > -3 > -4 > -5 > etc.
В случае «неверно отформатированного» ввода функция должна возвращать преобразованный результат, следуя приведенным ниже логическим примерам:
Если входное значение «нечисловое» или равно 0, функция должна вернуть 0. Я изо всех сил пытаюсь найти эффективное решение, которое может обрабатывать очень большие и очень маленькие числа без каких-либо ограничений. Я был бы признателен за любые рекомендации или примеры кода, которые могут помочь мне в этом.
function magic_inc(value, mode) {
if (typeof value !== 'number' || value === 0) {
return 0;
}
const multiplier = value < 0 ? -1 : 1;
value = Math.abs(value);
const increments = {
inc: [0.5, 0.6, 0.7, 0.8, 0.9],
dec: [0.5, 0.4, 0.3, 0.2, 0.1]
};
for (const increment of increments[mode]) {
if (value < increment) {
return multiplier * increment;
}
}
const power = Math.floor(Math.log10(value));
const first_digit = Math.floor(value / 10 ** power);
let result;
if (mode === 'inc') {
result = (first_digit + 1) * 10 ** power;
} else {
result = first_digit * 10 ** power;
}
return multiplier * result;
}
console.info(magic_inc(0.5, 'inc')); // Output: 0.6
console.info(magic_inc(-0.3, 'inc')); // Output: -0.2
console.info(magic_inc(1568.548, 'inc')); // Output: 2000
console.info(magic_inc(17, 'dec')); // Output: 9правильный вывод ==>
console.info(magic_inc(0.5, 'inc')); // Вывод: 0,6
console.info(magic_inc(-0,3, 'inc')); // Вывод: -0,2
console.info(magic_inc(1568.548, 'inc')); // Вывод: 2000
console.info(magic_inc(17, 'dec')); // Вывод: 9
но я получаю ==> 0,6 -0,5 2000 10
Что вы пытались решить проблему? Где ты застрял? Это так мало кода, что его отладка не должна быть такой сложной.
Я не могу понять, почему 17, 'dec' должен дать вам 9 в результате, а не 10, которые вы получаете? Имея проблемы с тем, чтобы на самом деле «увидеть» это в вашем объяснении того, как эти последовательности должны работать.
Здесь есть (по крайней мере) два разных вопроса. Ваше округление искаженного ввода - это совершенно отдельная проблема от фактической логики увеличения. Если я понимаю вашу логику приращения, вы хотите увеличивать самую значащую цифру до тех пор, пока она не завершится, и в этот момент вы хотите сдвинуть все число вверх или вниз на степень десяти, чтобы только самая значащая цифра могла когда-либо быть ненулевой?
Функция обрабатывает как режим «inc» (увеличение), так и режим «dec» (уменьшение) на основе заданной логической последовательности. Если значение меньше наименьшего приращения в соответствующем режиме, возвращается наименьшее приращение. В противном случае он увеличивает старшую цифру до тех пор, пока не достигнет следующего значения в последовательности или не перейдет к следующей степени десяти. Функция также заботится об округлении искаженного ввода, возвращая 0, если ввод не является допустимым числом или равен 0.



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


Я бы использовал научное обозначение, чтобы быстро получить коэффициент и показатель степени.
Очистка: обрезать коэффициент до целого числа.
Затем просто позаботьтесь об особых случаях, таких как 1 -> 0.9 и -0.9 -> -1, в противном случае увеличивайте/уменьшайте коэффициент.
function magic_inc(value, mode) {
if (typeof value !== 'number' || value === 0) {
return 0;
}
let [a,b] = value.toExponential().toLowerCase().split("e");
a = parseInt(a, 10);
if (mode === "inc") a = a===-1 ? -.9 : a+1;
if (mode === "dec") a = a===1 ? .9 : a-1;
return +`${a}e${b}`;
}
console.info(magic_inc(0.5, 'inc')); // Output: 0.6
console.info(magic_inc(-0.3, 'inc')); // Output: -0.2
console.info(magic_inc(1568.548, 'inc')); // Output: 2000
console.info(magic_inc(17, 'dec')); // Output: 9
Я бы предложил подойти к этому с помощью TDD — таким образом вы можете сосредоточиться на одном требовании за итерацию. Когда у вас что-то будет готово, вы сможете его усовершенствовать, сохраняя при этом существующие проходные тесты.