i am watching a crash course in svelte that creates a calculator app, also a beginner in javascript, when i do 1.1 x 3
it produces the result pic below but when i do 1.1 x 4
it show the correct result 4.4
, anybody can figure out why?
UPDATE: it is not a precision error, second code below is the solution
<script lang="ts"> const numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."]; const operations = ["/", "x", "-", "+", "="]; let selectedOperation = ""; let display = ""; let firstNumber = ""; let secondNumber = ""; let isDisplayingResults = false; // the selected operation in the calculator const handleOperationClick = (operation: string) => { // prevent selecting operation if firstNumber is empty if (!firstNumber) return; // if "=" is clicked check if secondNumber is empty then no action, else if (operation === "=") { if (!secondNumber) return; // check if numbers has decimal point const hasDecimalfirst = /\./.test(firstNumber); const hasDecimalsecond = /\./.test(secondNumber); let firstNum; let secondNum; // parse first number as integer if no decimal point else parse as float if (!hasDecimalfirst) { firstNum = parseInt(firstNumber); } else { firstNum = parseFloat(firstNumber); } // parse second number as integer if no decimal point else parse as float if (!hasDecimalsecond) { secondNum = parseInt(secondNumber); } else { secondNum = parseFloat(secondNumber); } let results = ""; // select operation based on selected operation switch (selectedOperation) { case "/": results = (firstNum / secondNum).toFixed(2); break; case "x": if (!hasDecimalfirst || !hasDecimalsecond) { results = (firstNum * secondNum).toString(); } else { results = (firstNum * secondNum).toFixed(2); } break; case "+": if (!hasDecimalfirst || !hasDecimalsecond) { results = (firstNum + secondNum).toString(); } else { results = (firstNum + secondNum).toFixed(2); } break; case "-": if (!hasDecimalfirst || !hasDecimalsecond) { results = (firstNum - secondNum).toString(); } else { results = (firstNum - secondNum).toFixed(2); } break; } display = results; isDisplayingResults = true; } selectedOperation = operation; }; const handleClear = () => { firstNumber = ""; secondNumber = ""; selectedOperation = ""; display = ""; isDisplayingResults = false; }; // the handler when selecting numbers in the calculator const handleNumberClick = (number: string) => { // clear all values after displaying the result when selecting a number if (isDisplayingResults) { handleClear(); } // if display is empty and selected number is 0 then no action // does not allow the initial number 0 assuming not float if (!display && number === "0") return; // if selected number is . and display already has . then no action // does not allow more than one . if (number === "." && display.includes(".")) return; // no selected operation yet if (!selectedOperation) { // if display is empty and selected number is . assign to firstNumber then display if (!display && number === ".") { firstNumber = "0."; return (display = firstNumber); } // if display is not empty append to current display and assign to firstNumber firstNumber = `${firstNumber}${number}`; return (display = firstNumber); } else { // already have a selected operation // if display is empty and selected number is . assign to secondNumber then display if (!display && number === ".") { secondNumber = "0."; return (display = secondNumber); } // if display is not empty append to current display and assign to secondNumber secondNumber = `${secondNumber}${number}`; return (display = secondNumber); } };</script><main><div class="calculator"><div class="results">{display}</div><div class="digits"><div class="numbers"><button class="btn btn-xlg" on:click={handleClear}>C</button> {#each numbers as number (number)}<button class={`btn ${number === "0" ? "btn-lg" : null}`} on:click={() => handleNumberClick(number)}> {number}</button> {/each}</div><div class="operations"> {#each operations as operation (operation)}<button class={`btn ${operation === selectedOperation ? "btn-silver" : "btn-orange"}`} on:click={() => handleOperationClick(operation)}> {operation}</button> {/each}</div></div></div></main>
SOLUTION:
// check if numbers has decimal point const hasDecimalFirst = /\./.test(firstNumber); const hasDecimalSecond = /\./.test(secondNumber); // Parse numbers as integers if no decimal point, else parse as floats const parseNumber = (number: string) => { return hasDecimalFirst || hasDecimalSecond ? parseFloat(number) : parseInt(number); }; const firstNum = parseNumber(firstNumber); const secondNum = parseNumber(secondNumber); let results = ""; // Perform the selected operation switch (selectedOperation) { case "/": results = (firstNum / secondNum).toFixed(2); break; case "x": results = (firstNum * secondNum).toFixed( hasDecimalFirst || hasDecimalSecond ? 2 : 0 ); break; case "+": results = (firstNum + secondNum).toFixed( hasDecimalFirst || hasDecimalSecond ? 2 : 0 ); break; case "-": results = (firstNum - secondNum).toFixed( hasDecimalFirst || hasDecimalSecond ? 2 : 0 ); break;