How to perform currency multiplication in the Brazilian format in js?

Asked

Viewed 453 times

1

I currently have the following monetary format:

2.222,57

But when I give a console.log() I see that it’s like a string:

console.log(this.produtos[i].price)
console.log(typeof (this.produtos[i].price))

If I try to convert this number to perform the operation, it returns NaN:

console.log(Number(this.produtos[i].price))

If I try with parseFloat(this.products[i].price), I get: 2.222 however I lose the value of the last two decimal places and when I perform multplications, for example:

let valor = parseFloat(this.produtos[i].price * 5)

I get: 11.11.

How can I perform mathematical operations in javascript with the Brazilian monetary format? If that’s not possible, how can I convert the 11.11 for the respective result 11.112,85 ?

  • 1

    Remove all non-numeric characters from the string to then perform the calculation, then divide by 10 and put the dots and the string back

  • I did so, but I lose the value of the two decimal places when I go to float: et valor = this.products[i]. price value.replace('.', ') value.replace(',', ') value = parseFloat(value) value = value * this.products[i]. amount

  • 5

    Mathematical operation has no relationship with monetary format (internally numbers have no formatting). Monetary format should only be applied in the display phase. It has to fix the data origin. With what was posted on the question will be a gambiarras show in the area of answers.

  • 1

    @veroneseComS so you divide by 100 at the end of the calculation (not by 10, I was wrong in the previous comment), makes the calculation as integer then goes back to decimal

  • @Bacco my frontend brings me the values with dots and commas, but I believe it has already given a clear

  • 1

    no sign thousands numbers, and the decimal separator is the point, not comma. Use replace stop solving this before converting to float

  • 3

    @veroneseComS ideally it would be good to already convert into numerical once you capture the data. Preferably the front already send right, if using ajax (even to be able to fix the locale, if the front is internationalizable)

Show 2 more comments

3 answers

2


As stated in the comments the best way to work with currency in trade is to remove non-numeric characters (grouping points and decimal comma) operationalize and readjust the result by dividing by 100.

The result of these operations results in an object Number which does not have mile grouping symbols and the decimal separator is the point. What makes it necessary to format that result for your needs.

To obtain culturally specific formatting you must use the method Number.prototype.toLocaleString() returns a string with a crop-sensitive representation for that number.

The first argument of toLocaleString() is local which informs the culture in which the number will be formatted. The value for this location is a string in the format BCP 74/RFC 5646 the values valid for local are listed in http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry. Here I used as local pt-BR.

The second argument is an object opção which are the formatting options, act as a more refined setting.

For your case I created two examples of formatting.

One formatting directly in currency which includes the monetary symbol for Reais (R$) which can be specified in the object opções setting the properties style: 'currency' to indicate the formatting in local currency and currency: 'BRL' to indicate the monetary symbol to be inserted in the case BRL which means Brazilian Real. Here is a list of the values for monetary symbols: ISO 4217 Current currency & funds code list.

The other example formatting as a decimal number, which I find the most appropriate to your question. I have set the properties of the object opções in style: 'decimal' to indicate the format in a decimal number, useGrouping: 'true'(default value, would not need to be used) to display the thousand character(. ) grouper, minimumFractionDigits: '2' to display a minimum of two decimal places and maximumFractionDigits: '2' (default value would not need to be used) to restrict formatting to a maximum of two decimal places.

//Não sabia do se tratava o seu estoque, criei um fictício.
const produtos = [{
    'name': 'perucas fio de prata',
    'price': '2.222,57'
  },
  {
    'name': 'perucas fio de ouro',
    'price': '5.000.326,90'
  },
  {
    'name': 'perucas fio de barbante',
    'price': '1.326,00'
  }
];



produtos.forEach((currentValue) => {
  // Remoção do caracteres não numéricos.
  let rawPrice = parseInt(currentValue.price.replace(/[.,]/g, ''));
  let quantity = parseInt(prompt(`Deseja comprar quantas ${currentValue.name} ?`));
  // Operacionalização e reajuste do resultado.
  let total = (rawPrice * quantity / 100);

  //Caso queira o valor formatado como moeda(incluio simbolo ISO 4217 para moeda).
  alert(`${currentValue.name}(resultado em moeda): ${quantity} X ${currentValue.price} = ${total.toLocaleString('pt-BR',{ style: 'currency', currency: 'BRL' })}`);

  //Caso queira o valor formatdo apenas como decimal com duas casas.
  alert(`${currentValue.name}(resultado em decimal): ${quantity} X ${currentValue.price} = ${total.toLocaleString('pt-BR',{ style: 'decimal', useGrouping: 'true', minimumFractionDigits: '2', maximumFractionDigits: '2' })}`);
});

1

You can also create a function that removes the dots and commas and work with the value in cents.

var currency = "100.100,10";
function onlyNumber(str) {
        if (str){
            if (typeof str === "number") {
                str = str.toString()
                return parseInt(str.replace(/[^0-9]/g, ""))
            }
            return str.replace(/[^0-9]/g, "");
        }
    }

parseint(onlyNumber(currency));

0

following what you ordered I would do mathematical operations with this number this way :

const produtos = ['2.222,57'];

let numero = produtos[0].replace(/[.]+/g, '');
numero = numero.replace(/[,]+/g, '.');
const valor = Number(numero);
console.log(valor * 5);

This is a case that happened to me when using a Input that formatted the value for the Brazilian monetary format.
I hope I’ve helped (^-^)

Browser other questions tagged

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