2

I have a full amount including VAT and i want to seperate the net price and the vat value.

The example is final price is 80.60 and the vat is 24%. What is the net price and what is the vat value? The answer should be net price is 65.00 and the vat value = 15.60.

For some reason typescript calculates 65.00 and 15.599999999999994. At the moment i dont want to round, the result should be 15.60 clearly though. I know there are other ansers on how to calculate the Vat , but my question is pretty specific whats wrong with my code and generated this decimal instead of 15.60.

Here is my code: component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-fpa',
  templateUrl: './fpa.component.html',
  styleUrls: ['./fpa.component.css']
})
export class FpaComponent implements OnInit {

    public netPrice:number;
    public fpaPercent:number=24;
    public fpaValue:number=0;
    public totalPrice:number;

public calc(calcType:string = ''){
    this.netPrice = this.totalPrice / ((this.fpaPercent/100)+1);
    this.fpaValue = this.totalPrice - this.netPrice;
}

}

component.html

                    <mat-form-field>
                        <input [(ngModel)]="netPrice" (keyup)="calc('byNetPrice');" matInput placeholder="Net Price">
                    </mat-form-field>

                    <mat-form-field>
                        <input [(ngModel)]="fpaPercent" (keyup)="calc();" matInput placeholder="% Vat">
                    </mat-form-field>

                    <mat-form-field>
                        <input [(ngModel)]="fpaValue" (keyup)="calc('byFpaValue');" matInput placeholder="Vat Value">
                    </mat-form-field>

                    <mat-form-field>
                        <input [(ngModel)]="totalPrice" (keyup)="calc('byFinalPrice');" matInput placeholder="Final Price" >
                    </mat-form-field>
Simos Fasouliotis
  • 1,383
  • 2
  • 16
  • 35
  • This is quite common. For one explanation of floating point rounding errors, see here: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Gonen I Dec 03 '17 at 09:35
  • So is there something I could do to my code to fix it ? – Simos Fasouliotis Dec 03 '17 at 09:37
  • You can round or truncate to a decimal point. You can see some other ideas here: https://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript – Gonen I Dec 03 '17 at 09:46

2 Answers2

2

It is because what we recognise as decimal numbers are encoded and stored in binary. Often a decimal number cannot be expressed precisely in binary, so there is a rounding error.

It looks like you just need to format the number to 2 decimal places.

You have a few options to do that:

  • You could use the built in JavaScript Number method, toFixed(2): (see MDN docs) in your controller logic to format the result of the subtraction to 2 decimal places.

  • You could use the Angular DecimalPipe in your controller logic: (see Angular docs)

    /*
        The Angular DecimalPipe can be more useful that toFixed()
        because it has a wider number of formatting options including
        the setting both the minimum and maximum number of digits after
        the decimal point. In this case it's specified a minimum AND
        maximum of 2 decimal places.
    
        Because decimals can be represented differently in different
        countries, the DecimalPipe constructor takes a locale.
    */
    const locale = 'en-US';
    const decimalPipe = new DecimalPipe(locale);
    this.fpaValue = decimalPipe.transform(this.totalPrice - this.netPrice, '.2-2');
    
  • If you were displaying the fpaValue elsewhere in your template, then you could use the decimal pipe in the template:

    {{ fpaValue | number:'.2-2' }}
    
lemmingworks
  • 169
  • 1
  • 5
1

First of all, it's not problem of TypeScript. It's behavior of Floating Point in JS: http://floating-point-gui.de/

Use:

this.fpaValue.toFixed(2);

You will get your answer upto 2 decimal points.

Gourav Pokharkar
  • 1,568
  • 1
  • 11
  • 33