Avatar billede kromix Nybegynder
05. november 2004 - 11:03 Der er 25 kommentarer og
1 løsning

mærklig float svar

jeg har fundet en mærklig fejl jeg ikke kan forklare

koden se således ud:
#include <stdio.h>
#include <conio.h>

void main()
{
  float var;

  var = 32000.2;
  printf("%f",var);
  getch();
}
meget simpel det skulle jo gerne skrive 32000.2 på skærmen men det jeg får er 32000.199219 er der nogen der kan forklare det ?

jeg bruger
Microsoft Visual C++ .NET v7.1.3088
Avatar billede sovsekoder Nybegynder
05. november 2004 - 11:07 #1
det har noget at gøre med præcisionen på en float. en double vil godt kunne håndtere det. Floaten indeholder et tal til en "vis" præcision
Avatar billede sovsekoder Nybegynder
05. november 2004 - 11:08 #2
..jo flere bytes din variabel er på desto bedre er præcisionen. en float fylder 4 bytes, en double fylder f.eks 8. (der er derfor også tilsvarende hastighedsforskel, når de benyttes)
Avatar billede erikjacobsen Ekspert
05. november 2004 - 11:11 #3
En double har også kun en vis præcision, og det vigtige at huske er at ikke
alt efter et komme kan repræsenteres eksakt.

Du bør derimod udskrive i den ønskede præcision, fx:

  printf("%.1f",var);
Avatar billede arne_v Ekspert
05. november 2004 - 11:16 #4
Brug Eriks løsning.

Du kan ikke regne med en eksakt repræsentation uanset størrelsen af
en floating point.
Avatar billede sovsekoder Nybegynder
05. november 2004 - 11:20 #5
til (sovsekoder 05/11-2004 11:08:39) - en tommelfinger regl er derfor: float til mindre præcise ting, double til mere præcise :)

hvis du er typen der gerne vil vide detaljerne om hvordan komma-tal kan repræsenteres, kan jeg anbefale at søge på nettet efter "floating point programming" ell. lign. hvis du vil vide mere indgående, hvorfor tingene er som de er. Problemet er det som erikj. siger: "det efter kommaet kan ikke altid repræsenteres præcist"
Avatar billede arne_v Ekspert
05. november 2004 - 11:20 #6
sovsekoder>

Jeg tror ikke at double er langsommere end float på moderne computere.
Avatar billede arne_v Ekspert
05. november 2004 - 11:23 #7
Bl.a. kan 0.1 ikke repræsenteres eksakt.
Avatar billede sovsekoder Nybegynder
05. november 2004 - 11:56 #8
Kommentar: arne_v
05/11-2004 11:20:25

ja det er da sikkert rigtigt! Jeg var lidt for mange år tilbage - selvom jeg bare er en kneit.

min fejl
Avatar billede kromix Nybegynder
05. november 2004 - 13:19 #9
mange tak for jeres svar har dog prøvet med double og få også en fejl der ligner dog længer ude ca 32000.0000000100000 eller noget i den stil... fik det forklarede men kan bare ikke helt forstå hvorfor et tal som lige har defineret bliver til noget andet
Avatar billede arne_v Ekspert
05. november 2004 - 13:29 #10
Som det allerede er skrevet flere gange så kan alle tal ikke repræsenteres
i floating point.

En float kan kun have ca. 4 milliareder forskellige værdier.

Den skal dække alle reelle tal mellem -10^38 og +10^38.

Der er uendeligt mange reelle tal i det interval.

Den kan derfor ikke have en værdi for alle reelle tal. Den tager
det tal den har en værdi for som er nærmest det den burde have.
Avatar billede kromix Nybegynder
05. november 2004 - 15:02 #11
tror jeg har fangede den nu... jeg troede der var 24bit til værdien (så kunne man jo repræsentere værdien ved at sige HEX "7d002 X 10^-3" altså 7d00.2) men der er kun 23. Så det er derfor den ikke kan skrive precis det tal men et tilnænmet ... Har jeg ret eller er jeg helt ved siden af ?????
Avatar billede arne_v Ekspert
05. november 2004 - 15:19 #12
Noget ved siden af.

Floating point (på alle gængse hardware platforme) er ikke 10 tals orienteret
men 2 tals orienteret.

Det er ikke:

(d0+d1/10+d2/100+d3/100+...)*10^n

men:

(b0+b1/2+b2/4+b3/8+...)*2^n
Avatar billede erikjacobsen Ekspert
05. november 2004 - 15:21 #13
Om det er 23 eller 24 bit gør ingen synderlig forskel ;) Selvfølgelig bliver
det lidt mere præcist hvis der var 24 bit. Hemmeligheden er 2-fold
  1) Det er baseret på 2-talssystemet (en halv, en fjerdedel, en ottendedel ..)
  2) Der er kun et endeligt antal bits.
Avatar billede kromix Nybegynder
08. november 2004 - 20:46 #14
kan i give mig den binær værdi for de 32000.2 eller 32000.199219 (som det bliver) tror det vil hjælpe mig med at forstå.

Det eneste jeg er sikker på er at en float består af 32 bit det første bit fortæller om det er + eller - de næste 8 er exponenten de sidste 23 er significand... hvordan den så kommer frem til et tal og om det er 10^4 eller om det er 2^4 der bliver ganget med
forstår jeg stadig ikke helt
tak for jeres toldmodighed :)
Avatar billede arne_v Ekspert
08. november 2004 - 21:07 #15
#include <stdio.h>

int main()
{
  float x = 32000.2;
  printf("%f\n",x);
  int ival = *((int *)&x);
  printf("%8X\n",ival);
  int ival2 = ival+1;
  float x2 = *((float *)&ival2);
  printf("%f\n",x2);
  return 0;
}

output:

32000.199219
46FA0066
32000.201172

viser at 32000.2 bliver gemt som 46FA0066 hex = 01000110111111000000000001100110 binært

den viser også at de 2 float som er nærmest 32000.2 er 32000.199219 og 32000.201172
(og den har selvfølgelig taget den første da den er tættest på)
Avatar billede kromix Nybegynder
09. november 2004 - 15:49 #16
ok...
det jeg så kommer frem til er at det første 0 viser det er positiv
de næste 8bit er exponenten 10001101 og de sidste 23bit 11110100000000001100110 er significanden

men hvordan får jeg det skrevet om... ekponenten er 141  skal man så sige
2^141 * significanden eller
significanden^141 eller
significanden^8D

kan ikke få noget af det til at give 32000.199219
hvordan bruger man eksponenten på significanten
håber ikke jeg giver dig grå hår :)
Avatar billede arne_v Ekspert
09. november 2004 - 16:05 #17
eksponenten bidrager som:

2^(141-127) = 2^14 = 16384

(1+1/2+1/4+1/8+1/16+1/64...)*16384 skulle gerne give 32000.199219
Avatar billede kromix Nybegynder
09. november 2004 - 21:02 #18
(1+1/2+1/4+1/8+0/16+1/32+0/64+0/128+0/256+0/512+0/1024+0/2048+0/4096+0/8192+0/16384+0/32768+1/65536+1/131072+0/262144+0/524288+1/1048576+1/2097152+0/4194304)*16384

er det sådan du mener for det giver kun 31232,39844
prøvede at køre det gennem excel :(
kan også være jeg har skrevet forkert et sted men har kigget efter :(
Avatar billede kromix Nybegynder
09. november 2004 - 21:04 #19
den klippede lidt af her er en forkortet udgave
(1+1/2+1/4+1/8+1/32+1/65536+1/131072+1/1048576+1/2097152)*16384
Avatar billede arne_v Ekspert
09. november 2004 - 21:04 #20
Det første 1 er implicit !
Avatar billede kromix Nybegynder
09. november 2004 - 21:07 #21
øh hvad er det :)
Avatar billede arne_v Ekspert
09. november 2004 - 21:10 #22
1+ bruger ikke et 1 tal fra cifrene.
Avatar billede arne_v Ekspert
09. november 2004 - 21:11 #23
1111010 -> 1+1/2+1/4+1/8+1/16+1/64
Avatar billede kromix Nybegynder
09. november 2004 - 21:11 #24
ok prøver lige igen giv mig et par min
Avatar billede kromix Nybegynder
09. november 2004 - 21:13 #25
nemlig ja nu passer det tak skal du have smid et svar så er der point :) Jubiiiiiiiiiii
Avatar billede arne_v Ekspert
09. november 2004 - 21:14 #26
svar
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