1

I am creating a calculator app to help with decimals and would like something to two decimal places like below:

number     output
------     -------
1          1.00
1.446      1.45
1.567      1.57

I have tried using toFixed(2) but I get an error as I'm using maths and not strings.

I've also tried using toPrecision(4) but I also get an error

Any help would be really appreciated.

import React from 'react';
import {StyleSheet, Text, View, TouchableOpacity, Vibration} from 'react-native';
import {useState} from 'react';
import { Entypo } from '@expo/vector-icons';

export default function App() {
  const [darkMode, setDarkMode] = useState(false);
  const [currentNumber, setCurrentNumber] = useState('');
  const [lastNumber, setLastNumber] = useState('');

  const buttons = ['C', 'DEL', '/', 7, 8, 9, '*', 4, 5, 6, '-', 1, 2, 3, '+', 0, '.', '=']

  function calculator() {
    
    let lastArr = currentNumber[currentNumber.length-1];
    
    if(lastArr === '/' || lastArr === '*' || lastArr === '-' || lastArr === '+' || lastArr === '.') {
      setCurrentNumber(currentNumber)
      return
    }
    else {
      let result = eval(currentNumber).toString();
      setCurrentNumber(result)
      return
    }
  }

  function handleInput(buttonPressed) {
    if(buttonPressed  === '+' || buttonPressed === '-' || buttonPressed === '*' || buttonPressed === '/') {
      Vibration.vibrate(35);
      setCurrentNumber(currentNumber + buttonPressed)
      return
    }
    else if (buttonPressed === 1 || buttonPressed === 2 || buttonPressed === 3 || buttonPressed === 4 || buttonPressed === 5 ||
            buttonPressed === 6 || buttonPressed === 7 || buttonPressed === 8 || buttonPressed === 9 || buttonPressed === 0 || buttonPressed === '.' ) {
      Vibration.vibrate(35);
    }
    switch(buttonPressed) {
      case 'DEL':
        Vibration.vibrate(35);
        setCurrentNumber(currentNumber.substring(0, (currentNumber.length - 1)))
        return
      case 'C':
        Vibration.vibrate(35);
        setLastNumber('')
        setCurrentNumber('')
        return 
      case '=':
        Vibration.vibrate(35);
        setLastNumber(currentNumber + '=')
        calculator()
        return
    }
    setCurrentNumber(currentNumber + buttonPressed)
  }
Frankinstyyn
  • 183
  • 1
  • 14

3 Answers3

5

From your question it is not clear where you want to perform the conversion. However, this should get you on the right track.

Both toFixed() and toPrecision() return a string representing a number. It's clear that you can't use the string for further calculations. In order to do so, use parseFloat() to get the floating point number from the string.

const floatingPointNumber = 1.567;
parseFloat(floatingPointNumber.toFixed(2));
parseFloat(floatingPointNumber.toPrecision(3));

Regarding toFixed() and toPrecision(), they actually perform the same operation but the first gives n decimal places while the latter gives n digits (see this question).

alexanderdavide
  • 1,487
  • 3
  • 14
  • 22
  • So in the end, I didn't use this code, but it did help me understand how to return the correct decimal places. I went with toFixed(2) on the 'result'. Thanks for commenting I really appreciate your help!! – Frankinstyyn Feb 23 '22 at 20:08
3

try this, may be helps you;

  function floatTwoDecFromString(value: string) {
    let newValue = value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');
    newValue =
      newValue.indexOf('.') !== -1
        ? newValue.slice(0, newValue.indexOf('.') + 3)
        : newValue;
    return newValue;
  }
Dhanesh M
  • 136
  • 3
  • Hey Danesh, thank you for commenting and providing some code. It was a little too complex for what I need, it turns out I only needed to add toFixed(2) to the 'result' which worked! I appreciate you spending time writing the function, keep up the good work! – Frankinstyyn Feb 23 '22 at 20:10
1

I understand that you are trying to round and not just clip to decimal places. You could use Math.round. While it rounds to the nearest int, you could use this trick to round decimals:

const roundToHundredths = num=>{
  let roundedNum = Math.round(num*100)/100
  // force 2 decimal places
  return roundedNum.toFixed(2);
}

Keep in mind that the value is now a string. Use parseFloat if other calculations have to be done

PhantomSpooks
  • 2,877
  • 2
  • 8
  • 13
  • So in the end, I didn't use this code. I went with toFixed(2) on the 'result'. Thanks for commenting though, I really appreciate your help and the function was well written and clear! – Frankinstyyn Feb 23 '22 at 20:09