-1

I'm trying to create a function that converts two strings to a float value.

Some external party created a theme with a backend where you should provide to values for a price:

  • priceBeforeComma
  • priceAfterComma

In the html this converts to:

<span>55,<sup>07</sup></span>

I need to do some calculations with the price as a float before splitting it up again for the html like you can see above.

I have a function that works pretty fine:

function parsePrice(price, priceDecimal) {
    return parseFloat(price + "." + priceDecimal);
}

However, the problem I'm facing is that let's say I provide 07 as the decimal like above, the leading zero is removed, returning 55,7.

There is quite a big difference between 55,07 and 55,7. I expect to get back the zero as well like 55,07.

Any help will be much appreciated.

Mentos93
  • 581
  • 1
  • 7
  • 28
  • 3
    Why don't you pass in Strings instead? – Unmitigated Apr 08 '19 at 14:42
  • 1
    as @hev1 said, pass strings direclty, i just tested it, it works with strings; parsePrice("55", "07") will give you 55.07 – Mehdi Benmesssaoud Apr 08 '19 at 14:44
  • 2
    Not exactly an answer to your question, but a suggestion: Don't do financial calculations with floating point arithmetic. Rather, work in pennies (or whatever the smallest unit is of the currency you are working in.) So for example $3.75 + $4.25 = 375 cents + 425 cents = 800 cents = $8.00. Otherwise you risk coming up with answers like $3.75+$4.25=$7.999999... , which you can fix by rounding, but why? Money isn't inherently floating point, so work in fixed precision. It will be faster, too. – Duncan Apr 08 '19 at 14:49
  • 1
    @hev1 silly one on my side. I thought they were string already. Should have done my homework better before asking! Thank you!! – Mentos93 Apr 08 '19 at 14:55
  • @Mentos93 No problem. – Unmitigated Apr 11 '19 at 01:13

5 Answers5

1

Your Code is right

function parsePrice(price, priceDecimal) {
return parseFloat(price + "." + priceDecimal);
}
parsePrice("55", "07");

if you send parsePrice("55","07") so you do not need to divide it by 100 because maybe you send it 007 then you should divide it by 1000. But your code will work properly if send string

Shojaeddin
  • 1,851
  • 1
  • 18
  • 16
0

This might be overkill, but you could use something that provides complete control over how numbers are converted to strings, and vice versa, for example: https://github.com/alexei/sprintf.js I have not used that library, but it promises to provide the same functionality as C printf, which would allow you to keep leading zeros. See the answer to the "C" language question here: Printing leading 0's in C?

(But, as an aside, also see my comment above - generally it's better to do financial calculations in integer arithmetic rather than floating point.)

So my suggestion would be to do this instead:

function price(dollars, cents) { // adjust for your currency
   return parseInt(dollars)*100 + parseInt(cents); 
}

function dollarsAndCents(price) {
    let sign = "+";
    if (price<0) {
        sign = "-";
        price = -price;
    }
    let cents = price % 100;
    let dollars = (price-cents)/100;
    dollars = dollars.toString();
    cents = cents.toString();
    if (cents.length<2) cents = "0" + cents;
    return {sign: sign, dollars: dollars, cents: cents}
}

let price1 = price ("55", "07");
let price2 = price ("99", "99");
let total = price1 + price2;

console.log(dollarsAndCents(total))
//{ sign: '+', dollars: '155', cents: '06' }

let refund = -12345
console.log(dollarsAndCents(refund))
//{ sign: '-', dollars: '123', cents: '45' }

There you go, that's a pretty complete solution! Even handles negative amounts.

Duncan
  • 507
  • 3
  • 14
0

Floats represent 07 as 07.0, so to get this to work correctly you'll need to write it as 0.07.

Here's what worked for me:

function parsePrice(price, priceDecimal) {
    return parseFloat(price + priceDecimal); 
}

var output = parsePrice(57, 0.07); 

document.getElementById("test").innerHTML = output.toString().replace(".", ",");
<p id="test"></p>
Andrew
  • 121
  • 11
0

You should pass in Strings to your function instead by putting quotes around your numbers. Using numbers will always have the caveat of removing any leading zeroes.

function parsePrice(price, priceDecimal) {
    return parseFloat(price + "." + priceDecimal);
}
parsePrice("55", "07");
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
-1

Why not parse them separately as integers and add them together in the right proportions?

    function parsePrice(price, priceDecimal) {
        return parseInt(price) + (parseInt(priceDecimal) / 100);
    }

console.log(parsePrice("55", "07"));
phuzi
  • 12,078
  • 3
  • 26
  • 50
  • If `"55"` and `"07"` were the parameters to OP's function, it would work fine as it is – adiga Apr 08 '19 at 14:47
  • What if the priceDecimal is 005 ? or 00005 ? – Moad Ennagi Apr 08 '19 at 14:47
  • 1
    @MoadEnnagi OP can adjust as required, alkthough nothing has been mentioned about accuracy and given they've only mentioned "55.07" then that's enough accuracy for the question – phuzi Apr 08 '19 at 14:48
  • This illustrates my point - generally better to do money calculations using integers rather than floating point. You might find a pesky rounding error that results in a total price being off by a penny. (That's how the Richard Prior character got rich in the Superman movie, remember?) – Duncan Apr 08 '19 at 14:59