This is happening because you are not passing numerical values, but yes string
s that in some cases (given the coercive behavior of Javascript) will be converted, but in others, not.
Thus, as the property value
always returns a string
, you must, before using them, convert them to the appropriate type:
function sortear(){
var min = parseInt(document.getElementById("minimo").value, 10);
var max = parseInt(document.getElementById("maximo").value, 10);
var sorteio = Math.floor(Math.random() * (max - min) + min);
document.getElementById("resultado").innerHTML = sorteio;
}
<div>
<p>Insira o valor mínimo: <input type="number" name="minimo" id="minimo"></p>
</div>
<div>
<p>Insira o valor máximo: <input type="number" name="maximo" id="maximo"></p>
</div>
<div>
<button onclick="sortear()">Sortear</button>
</div>
<div>
<h1 id="resultado"></h1>
</div>
In this case, we use the parseInt
to perform the conversion of string
for number
. Other options for this conversion are builder Number
or parseFloat
. You can also use the unary operator +
, but I personally don’t like this last option.
Now I will actually explain what was going on when you were using the wrong types. First, we need to analyze the expression to be interpreted by Javascript:
Math.floor(Math.random() * (max - min) + min);
Supposing max
be it "15"
and min
be it "5"
(note that both are strings), we can assume the following:
Math.floor(Math.random() * ("15" - "5") + "5");
First, Javascript will evaluate the subtraction within the parentheses, which give preference to this evaluation. As the operator -
, in Javascript, means arithmetic subtraction exclusively, the two operands are correctly converted to type number
before the operator performs the subtraction.
Once we have the result of the previous subtraction (10
- note that now it is a number), we will multiply with the value returned by Math.random
, which is also a number.
Finally, the product will be concatenated (+
) with the value of min
(which was to be a sum). This is because, in Javascript, the binary operator +
may have different meanings depending on the type of your operands. I explain this better in this question: How the "+" operator works in Javascript?.
So, keeping the values max
and min
as string, we will have the following evaluation step by step:
Math.floor(Math.random() * ("15" - "5") + "5");
Math.floor(Math.random() * 10 + "5");
Math.floor(0.8879528248948558 * 10 + "5");
- assuming that Math.random
return 0.8879528248948558
.
Math.floor(8.879528248948558 + "5");
Math.floor("8.8795282489485585");
- Note that the "5"
was concatenated at the end of the product.
8
— Math.floor
, according to the specification, converts the type to number
automatically.
So, as you can see, this automatic type coercion of Javascript is really confusing and full of subtleties that can affect the robustness of the code. Therefore, it is always ideal that you convert the guys explicitly for the numeric value if you want to work with mathematical operations.