Problem with toFixed and decimals

Asked

Viewed 157 times

1

My code reads the value with a decimal place, however the toFixed(1) transforms the variable A string:

function VerificaNota(){
	let x = 0
	let valor = parseFloat(prompt('Digite a nota do aluno'));
  while(x < 1) {
    if(valor >= 0 && valor <= 10) {   
      x++;
      return parseFloat(valor)
    }
    else {
      valor = prompt();
    } 
  }
}

let A = VerificaNota();
A = A.toFixed(1);
alert(A)
let soma = A + A;
alert(soma); 

  • 1

    Yes, the .toFixed converts into String. Isn’t that what you want? What’s the idea of using the .toFixed? is to round off the decimals?

  • Because I’m solving an exercise where A must read a value with a decimal place, so if I type 1, A must recever 1.0 understood?

  • Okay, you’re going to compare more notes or you just want to convert the note that’s received into prompt and display to 1 decimal place?

1 answer

4

First, some details on your function reading the note. First you do:

let valor = parseFloat(prompt('Digite a nota do aluno'))

That is to say, valor will be a number (because that’s what parseFloat returns). Then, inside the while, you do:

return parseFloat(valor)

That is, you try to convert a number to a number. But valor is already a number (because the return is inside the if which has already checked whether the value is valid), so you do not need to call parseFloat again. Just return valor directly.

Another detail is the logic of loop. You don’t need this variable x to know if you must continue asking to enter a valid number, just do something like this:

function lerNota() {
    while (true) {
        let valor = parseFloat(prompt('Digite a nota do aluno'));
        if (valor >= 0 && valor <= 10) {   
            return valor;
        } else alert('Nota deve ser um número entre 0 e 10');
    } 
}

let nota = lerNota();
console.log(nota);

If the value is between 0 and 10, it returns. Otherwise, it displays a message and asks the user to type the note again. The return returns the value and exits the function, interrupting the loop.

If no number is entered (for example, if the user type "abc"), parseFloat returns NaN, and as this is a special value that is not greater, equal, nor less than any number, will not enter the if, then the function also already checks when a number is not typed.


Now let’s go to the calculation itself. I understood that you want to calculate twice the typed note, and show the result with only one decimal.

I saw that you want the typed note also to have only one decimal place. One option is to use toFixed, that turns it into string, and then turn this string into number again, as already done in the other answer (although it is also possible just by making some calculations, as we will see at the end).

But there’s a detail, toFixed may or may not round off the value, depending on the case:

function arredonda(n) {
    console.log(`${n} => ${n.toFixed(1)}`);
}

arredonda(1.47); // 1.5
arredonda(1.44); // 1.4

That is, if the user type "1.47", the note shall be transformed into 1.5, and the double of it will be 3. But if the idea was not to round the original value, then the note should be transformed into 1.4, and double would be 2.8. Which of these options do you want?

Regardless of the option, you do not need to use toFixed to turn into string, then convert to number again. Just do some calculations: multiply by 10, round (or not) and divide by 10.

There is another possibility: do not delete the decimal places of the note, and only do this in the final result. In this case it can also make a difference, because twice 1.47 is 2.94. And if we apply toFixed(1) at this value, the result will be 2.9.

That is, 3 different results, depending on how you handle the data. In the code below we can see these 3 options:

// 1.47 se torna 1.5
function arredonda(valor) {
    // poderia ser parseFloat(valor.toFixed(1)), mas preferi fazer contas :-)
    return Math.round(valor * 10) / 10;
}

// 1.47 se torna 1.4
function naoArredonda(valor) {
    return Math.floor(valor * 10) / 10;
}

// dobra o número e aplica toFixed (que arredonda o resultado)
function dobro(valor) {
    return (2 * valor).toFixed(1);
}

let nota = 1.47;

// arredonda a nota e calcula o dobro
console.log(dobro(arredonda(nota))); // 3.0

// pega somente a primeira casa decimal, sem arredondar, e calcula o dobro
console.log(dobro(naoArredonda(nota))); // 2.8

// preserva as casas decimais da nota, e aplica toFixed somente no dobro
console.log(dobro(nota)); // 2.9

When calculating double, I used toFixed in the result, but you can also use the other methods (rounding or not) to display double the way you think best.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.