#javascript #math
#javascript #математика
Вопрос:
Я не смог найти на w3schools.com оператор сравнения, который проверяет, равно ли сгенерированное число определенному типу чисел.
Есть ли вообще способ сформулировать if statement
без изменения innerHTML
свойства ссылки.
Например, в следующей упрощенной версии моего кода: он должен отображать только такие числа, как 6, 3.1, 4.05, 53.65 (эти числа имеют 2, 1 или вообще не имеют чисел после десятичной точки и подсчитываются с шагом 0.05)
function F1() {
x = document.getElementById("x").innerHTML = Math.random() * 100;
if (x !== "0.05") {
F1();
}
if (x !== "0.1") {
F1();
}
if (x !== "1") {
F1();
}
}
<button onclick="F1()"> New </button>
<p id="x"></p>
Комментарии:
1. (оффтопик) Если вы не используете lnline
style=""
(надеюсь, вы этого не делаете) — пожалуйста, прекратите использовать встроенныеon*=""
обработчики. Это «осколок» выполняет отладку. JS должен быть только в одном месте, и это вашscript
файл или тег. И прекратите использовать w3schools в качестве учебного ресурса. Все еще на сегодняшний день (2020) они полны дерьмовых примеров и нерелевантных образцов кода и сертификатов.2. Было бы намного проще просто сгенерировать правильный тип числа напрямую, вместо того чтобы проверять полностью случайные числа снова и снова (и это может занять много времени, чтобы найти нужный вам тип).
x = (0.05 * Math.round(Math.random() * 100 / 0.05)).toFixed(2)
Ответ №1:
Используйте оператор модуля
Однако деление на дробь (.05) может привести к несовершенным результатам, поэтому лучше умножить на 20 и проверить, есть ли напоминание о дроби (модуль 1).
Ответ @ Thomas Sablik также действителен и объясняет умножение на 20.
const isPoint05 = x => x * 20 % 1 === 0;
const test = (...args) => args.forEach(x => console.log(x, isPoint05(x)));
test(6, 3.1, 4.05, 53.65, 3.254, 6.22, 7.77, 7.33);
И чтобы проиллюстрировать проблему с разделением на дроби (зависит от реализации JavaScript, я получаю 0.049999999999999614 в Chrome):
console.log(7 % 0.05);
Ответ №2:
Вы могли бы умножить число на 20 и округлить его:
if (Math.round(x * 20) !== x * 20) {
// not counted in 0.05 steps, eg. 1.234
} else {
// counted in 0.05 steps, eg. 1.25
}
Этот оператор if проверяет, «эти числа имеют 2, 1 или вообще не имеют чисел после десятичной точки и подсчитываются с шагом 0,05», потому что числа, подсчитанные с шагом 0,05, умноженным на 20, являются целыми числами ( Math.round(x * 20) !== x * 20
равно false), например:
0.05 * 20 = 1
1.25 * 20 = 25
и другие числа не являются целыми числами ( Math.round(x * 20) !== x * 20
верно), например:
0.04 * 20 = 0.8
1.251 * 20 = 25.2
Но использовать этот оператор if с Math.random
— плохая идея, потому что высока вероятность того, что он Math.random
сгенерирует так много других чисел, что рекурсия вызовет переполнение стека.
Лучший подход — сгенерировать нужные числа с помощью
x = Math.round(Math.random() * 20 * 100) / 20
Комментарии:
1. Почему вы умножили его на 20? Мне любопытно.