1

I was wondering if there's a way to improve and make this function faster, less resource consuming and more readable:

calculateMerchantEarnings(original_price) {
    const processor_percentage = Math.round((original_price * 0.029 + Number.EPSILON) * 100) / 100;
    const processor_flat = 30; // in cents
    const myfees_and_processing_fees = processor_percentage + processor_flat + 100;
    const final_price_minus_deductions = original_price - myfees_and_processing_fees;
    const final_price_in_cents = Math.round((final_price_minus_deductions + Number.EPSILON) * 100) / 100;
    return (
      Math.round((final_price_in_cents / 100 + Number.EPSILON) * 100) / 100
    );
  }

What I do is:

  1. Pass the original_price in cents
  2. Calculate CC Processor percentage fees
  3. Add my fees ($1) and the processor's percentage and flat fee
  4. calculate the final price by deducting the total fees from the original_price
  5. Round up the final price in cents
  6. Convert the final price to dollars and round up

I have a feeling I may be able to do all this with one line :)

Ben
  • 2,957
  • 2
  • 27
  • 55
  • Why are you adding `Number.EPSILON`? – Barmar Aug 20 '21 at 16:37
  • For precision following this popular comment: https://stackoverflow.com/a/11832950/2752719 – Ben Aug 20 '21 at 16:38
  • what is *CC Processor percentage fee* (2.9 or 3 percent) and what *flat fee* (always 30 cent?)? – Nina Scholz Aug 20 '21 at 16:42
  • Nina, yes - 2.9% = $0.30 (stripe) – Ben Aug 20 '21 at 16:43
  • 1
    It's six lines of code. Nothing you can do to this will improve its speed such that you will recover the time you have spent on it. Unless there is demonstrably a problem here, don't micro- optimise. Spend your time on more useful things. – Tangentially Perpendicular Aug 20 '21 at 16:44
  • I'm not sure why you would need to profile this, on my laptop it took 10000000 iterations of this function to get a noticeable delay. Basic math operations are very fast. – Samuel Aug 20 '21 at 16:54
  • I can understand my question may anger and confuse some developers. But please see Nina's one liner function that does the same as my elaborate function and understand that peer developers will rather read through her function than go line by line through mine when working on a shared code. – Ben Aug 20 '21 at 16:59
  • Because it's important, I'll point out that "money math" with binary floating-point numerics is highly problematic. – Pointy Aug 20 '21 at 16:59
  • there's no logical reason to round a number 3 times in the same function. only round as the final step. also not sure why Number.EPSILON would be needed for such a simple calculation. – Rick Aug 20 '21 at 16:59
  • @ben nobody here is angry or confused, but think on this: when you or your peers return to this in six months to change the processor percentage, in which of the two versions will it be easier to find the correct number and change it? – Tangentially Perpendicular Aug 20 '21 at 22:32
  • @TangentiallyPerpendicular in Nina's version. Much easier to follow. All I do is add a short comment next to it to explain what is going on. – Ben Aug 20 '21 at 22:35

1 Answers1

2

Basically, you could add all into a single expression.

function calculateMerchantEarnings(original_price) {
    const processor_percentage = Math.round((original_price * 0.029 + Number.EPSILON) * 100) / 100;
    const processor_flat = 30; // in cents
    const myfees_and_processing_fees = processor_percentage + processor_flat + 100;
    const final_price_minus_deductions = original_price - myfees_and_processing_fees;
    const final_price_in_cents = Math.round((final_price_minus_deductions + Number.EPSILON) * 100) / 100;
    return Math.round((final_price_in_cents / 100 + Number.EPSILON) * 100) / 100;
}

const fn = x => Math.round(x * 0.971 - 130) / 100;

console.log(calculateMerchantEarnings(1000));
console.log(fn(1000));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392