Obliczanie wartości brutto z ceny netto

0

Wyliczam wartość brutto z ceny jednostkowej netto, robię to w ten sposób:

  1. Pobieram cenę netto z liczby float sformatowanej do dwóch miejsc po przecinku
  2. Następnie aby uzyskać wartość netto typu float mnożę ją przez ilość (int)
  3. Potem z wartości netto wyliczam kwotę podatku typu float (np. 22% czyli mnożę wartość netto * 0,22)
  4. Na końcu sumuję dwie zmienne float, czyli wartość netto i kwotę podatku i zapisuję do stringa formatując do dwóch liczb po przecinku, używając funkcji Format.

Problem w tym, że otrzymuję niedokładne wyniki. Czyli np. już na ilości równiej 2 przy cenie netto = 8 zł otrzymuję cenę brutto za dużą o jeden grosz (jedną setną). Przy ilości = 10 różnica wzrasta już do 3 groszy. Przy testowaniu tylko raz się zdarzyło, że wynik był o jeden grosz mniejszy, przeważnie kwoty brutto są ciut za duże.

Co robię źle? ;-(

0

Tak to wygląda w kodzie:

[code]
int Ilosc = StrToInt(Edit1->Text);
float WartoscNetto = Ilosc * Table1->FieldByName("Cena_netto")->AsFloat;

int Vat = Table1->FieldByName("VAT_procent")->AsInteger;
AnsiString UlamekA;
if (Vat < 10)
UlamekA = "0,0" + IntToStr(Vat);
else
UlamekA = "0," + IntToStr(Vat);
float Ulamek = StrToFloat(UlamekA);
float KwotaVAT = WartosscNetto * Ulamek;

float CenaBrutto = WartoscNetto + KwotaVAT;
TVarRec VarRec = CenaBrutto;
AnsiString Cena_bruttoA = Format("%.2f", &VarRec, 1);
Table1->FieldValues["Cena_brutto"] = Cena_bruttoA;
[/code]

Dodam, że wszystkie kwoty w bazie danych mam jako stringi do dwóch miejsc po przecinku.

0

Widocznie float jest za mało dokładne. Spróbuj z double.

0

Na moje oko idac najprostszym tokiem rozumowania to przyczyna niedokladnych wynikow jest to, ze:

przykladowo cena detaliczna to 1,547 zł netto
po zaokragleniu podawana jest ona jako 1,55 zł netto

i teraz jesli chcemy obliczyc cene netto 25 artykułow to:
1,547 * 25 = 38,675 (38,68 zł)<- cena faktyczna bez zaokraglania
1,55 * 25 = 38,75 <- przy zaokragleniu

w takim wypadku błąd wynosi 7 gr

Wiec jesli obliczasz cene to do ilu bys jej nie zaokraglal przy wyswietlaniu to zawsze przy obliczeniach bierz pod uwage faktyczna cene. :P tak mi sie wydaje, ale czy tak faktycznie jest to nie wiem bo nie czytlalem tego kodu co wkleiles :]

0

1. to:

float WartoscNetto = Ilosc * Table1->FieldByName("Cena_netto")->AsFloat;

zastąpił bym tym:

#include <math.hpp>
float WartoscNetto = SimpleRoundTo(((float)Ilosc*Table1->FieldByName("Cena_netto")->AsFloat), -4);

2. zamiast tego:

if (Vat < 10)
UlamekA = "0,0" + IntToStr(Vat);
else
UlamekA = "0," + IntToStr(Vat);
float Ulamek = StrToFloat(UlamekA);

użyłbym:

float Ulamek = (float)Vat/100.f;

1 użytkowników online, w tym zalogowanych: 0, gości: 1