Avatar billede normann Nybegynder
20. november 2002 - 12:44 Der er 2 kommentarer og
2 løsninger

Simpelt atof(str) (C)

Hejsa

Jeg har et program som læser en masse tal af formen xxxx.xx
Altså altid med 2 decimaler. Når jeg bruger atof på en streng indeholdende et sådant tal fx. "1200.22" så får jeg fx 1200.2197696 ell. lign.

Mine spørgsmål er nu :

1.Hvorfor det ?
2.Hvordan runder jeg nemmest muligt af til 1200.22

Mvh.
Bo
Avatar billede soepro Nybegynder
20. november 2002 - 13:16 #1
Ad 1) Fordi float er en tilnærmet værdi i kraft af den måde tallet gemmes på. Du vil således (normalt) ikke kunne få følgende til at give 1:

float result = 0.0;
for (int idx = 0; idx < 100; idx++)
  result += 0.01f;

Du er nødt til at basere dig på andre datatyper, f.eks. BCD (Binary Coded Decimal) hvis det skal blive helt præcist.

Ad 2)
En nemmeste måde at afrunde til 2 decimaler er:

float rnd2dec(float v)
{
  long temp = (long)(v * 100L);
  return (float)(temp / 100);
}

Jeg har selv oplevet at tallene bliver "bedre" (altså mere præcise på de første 2-3 decimaler) hvis du bruge double eller long double i stf. float. Jeg har lavet en applikation med beløb - dem endte jeg med simpelthen at gemme i ører, og så ændre det til kr. når de blev skrevet ud:

#define kr_del(x) (x / 100)
#define ore_del(x) (x % 100)
printf("Kr: %08d%c%02d", kr_del(beloeb), DecimalPoint, ore_del(belob));
Avatar billede arne_v Ekspert
20. november 2002 - 13:18 #2
Floating point tal er ikke altid lige gode
til at repræsentere decimal tal.

Allerførst skal du sørge for konsekvent at
bruge double i.s.f. float.

Det allerbedste ville være hvis du kunne
opbevare tallene som int (120022 i.s.f. 1200.22).

Hvis du endelig vil prøve at konvertere, så prøv med:

((int)(x*100))/100.0
Avatar billede soepro Nybegynder
20. november 2002 - 13:20 #3
Undskyld rnd2dec() laver *IKKE* AF-runding, den laver NED-runding. AF-runding ser sådan her ud:

float rnd2dec(float v)
{
  long temp = (long)((v + 0.005) * 100L);
  return (float)(temp / 100);
}

Jeg formoder at du også kender printf() funktionalitet til afrunding til et bestemt antal decimaler:

float beloeb = 1022.22;
printf("Kr : %05.02f", beloeb);

(Fem tal foran decimalpunkt med foranstillede nuller - altid 2 decimaler.)
Avatar billede arne_v Ekspert
20. november 2002 - 13:29 #4
He he.

Min kode har faktisk samme fejl.

((int)(x*100+0.5))/100.0
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester