This is a Calculator I'm building. Whenever I try to do small subtractions or addition (e.g. 7.8 - 7.6) it shows up a very long strand of unnecessary decimals (0.20000000000000018).
You can find the entire code here https://github.com/Fallingstar-0/Calculator.
I have tried Math.floor, Math.ceil; but nothing works. I looked up on the internet and it seems it's one of JS's shenanigans.
For easier readability I'll post the snippet below:
const formatter = new Intl.NumberFormat(undefined, {
maximumFractionDigits: 0,
})
const format = (number) => {
if (number == null) return
const [integer, decimal] = number.split(".")
if (decimal == null) return formatter.format(integer)
return `${formatter.format(integer)}.${decimal}`
}
export const ACTIONS = {
ADD_DIGIT: "add-digit",
ADD_OPERATION: "add-operation",
EVALUATE: "evaluate",
CLEAR: "clear",
DELETE_DIGIT: "delete-digit",
}
const reducer = (state, { type, payload }) => {
if (type === ACTIONS.ADD_DIGIT) {
if (state.overwrite) {
return {
...state,
currentOperand: payload.digit,
overwrite: false,
}
}
if(!state.currentOperand && payload.digit === ".") {
return {
...state,
currentOperand: `0.`
}
}
if (payload.digit === "0" && state.currentOperand === "0") return state
if (payload.digit === "." && state.currentOperand.includes(".")) {
return state
}
return {
...state,
currentOperand: `${state.currentOperand ?? ""}${payload.digit}`,
}
}
if (type === ACTIONS.CLEAR) {
return { state }
}
if (type === ACTIONS.ADD_OPERATION) {
if (state.currentOperand == null && state.previousOperand == null) {
return state
}
if (state.operation && state.currentOperand == null) {
return {
...state,
operation: payload.operation,
}
}
if (state.previousOperand && state.currentOperand) {
return {
...state,
previousOperand: evaluate(state),
operation: payload.operation,
currentOperand: null,
}
}
return {
...state,
previousOperand: state.currentOperand,
operation: payload.operation,
currentOperand: null,
}
}
if (type === ACTIONS.DELETE_DIGIT) {
if (state.overwrite) {
return {
...state,
currentOperand: null,
overwrite: false,
}
}
if (!state.currentOperand) {
return state
}
if (state.currentOperand.length === 1) {
return {
...state,
currentOperand: null,
}
}
return {
...state,
currentOperand: state.currentOperand.slice(0, -1),
}
}
if (type === ACTIONS.EVALUATE) {
if (!state.currentOperand && !state.previousOperand) {
return state
}
if (state.currentOperand && state.previousOperand) {
return {
...state,
currentOperand: evaluate(state),
previousOperand: null,
operation: null,
overwrite: true,
}
}
}
}
// evaluate function
const evaluate = ({ currentOperand, previousOperand, operation }) => {
const prev = parseFloat(previousOperand)
const curr = parseFloat(currentOperand)
let computation = ""
if (isNaN(prev) || isNaN(curr)) {
return ""
}
switch (operation) {
case "/":
computation = prev / curr
break
case "*":
computation = prev * curr
break
case "+":
computation = prev + curr
break
case "-":
computation = prev - curr
break
}
return computation.toString()
}
function App() {
const [{ currentOperand, previousOperand, operation }, dispatch] = useReducer(
reducer,
{}
)
return (
<div>
...Rest of code