Avatar billede r.hegaard Nybegynder
25. september 2002 - 11:22 Der er 12 kommentarer og
4 løsninger

Cosinus

Jeg har lavet en knap med en cosinus funktion, men den virker ikke helt efter hensigten. Min knap har funktionen:
procedure TRegner.CosKnapClick(Sender: TObject);
begin
  TalEdit.text:= FloatToStr(Cos(DegToRad(StrToFloat(TalEdit.Text))));
end;
Når jeg tager cosinus til 0, så giver den 6,12303176911189E-17
Det er ganske vist meget tæt på 0, men hvorfor giver det ikke 0, og hvordan får man den til at give nul ???
Avatar billede ladyhawke Novice
25. september 2002 - 11:48 #1
Nu er computerberegninger sjældent eksakte (numeriske tilnærmelser), men du kan da vise resultatet som en float, med f.eks. 5 decimaler...

Måske skyldes dit problem at du regner med floats, så du tager cosinus til 0.0 i stedet for 0, det giver matematisk det samme, men ikke for en computer ;o)
Avatar billede speedy Nybegynder
25. september 2002 - 11:50 #2
1) Cosinus til 0 giver 1

2) Det virker fint når jeg bruger dit eksempel. Altså hvis jeg skriver 0 i feltet og udfører din beregning skriver den 1 i samme felt.

/SpEeDy
Avatar billede speedy Nybegynder
25. september 2002 - 11:57 #3
Men du burde nok sætte max antal decimaler på via RoundTo funktionen:

  TalEdit.text:= FloatToStr(RoundTo(Cos(DegToRad(StrToFloat(TalEdit.Text))), -20));

20 er antallet af decimaler.

Hvis du ikke bruger den, vil cos(90) bliver det tal som du beskrev, men når du benytter funktionen bliver den 0.

/SpEeDy
Avatar billede r.hegaard Nybegynder
25. september 2002 - 12:10 #4
speedy > Jeg skrev lige forkert, der skulle have stået:
Når jeg tager cosinus til 90, så giver den 6,12303176911189E-17
Det er ganske vist meget tæt på 0, men hvorfor giver det ikke 0, og hvordan får man den til at give nul ???
Hvad er problemet her ??
Avatar billede speedy Nybegynder
25. september 2002 - 12:22 #5
Prøv at læse mit svar 11:57:09

/SpEeDy
Avatar billede speedy Nybegynder
25. september 2002 - 12:22 #6
Der er altså ikke det problem når du bruger RoundTo

/SpEeDy
Avatar billede r.hegaard Nybegynder
25. september 2002 - 12:32 #7
Nej, det er ikke noget problem,  men jeg forstår ikke hvorfor den ikke giver det rigtige resultat.....
Funktionen skulle gerne kunne gøre det meget præcist, det bliver det jo ikke hvis den runder af.
Avatar billede loke-liscom Nybegynder
25. september 2002 - 13:07 #8
FloatToStr(
Cos(
DegToRad(
Så vidt jeg husker er float 32 bit. undervejs igennem disse 3 funktioner kunne det godt tænkes at en af dem kommer til at afrunde til 16 bit. Da det ikke vil være en afrunding men en "afklipning" vil dette kunne skyldes denne minimale afvigelse.

//Klaus
Avatar billede ladyhawke Novice
25. september 2002 - 13:08 #9
Tjek lige det med floats!! Prøv at lave en udregning med tallet 90 (som integer, hvis du kan) og se hvad resultatet bliver?

Normalt vil et kommatal givel skæve tal som du angiver i spørgsmålet, fordi det tvinger computeren til at udregne værdien ved hjælp af en nummerisk metoden (som ikke er eksakt).
Avatar billede loke-liscom Nybegynder
25. september 2002 - 13:13 #10
6,12303176911189E-17 = 0,0000000000000000612303176911189
:-)
Avatar billede r.hegaard Nybegynder
25. september 2002 - 13:21 #11
Jeg ved det, det irriterer mig bare......
Avatar billede loke-liscom Nybegynder
25. september 2002 - 13:44 #12
Btw. min kommentar var et svar.... :-)
Avatar billede loke-liscom Nybegynder
25. september 2002 - 23:27 #13
Hmmm.... nu har jeg kigget efter.
Hvad er det eneste i funktionerne der ikke er præcist?

Der er jo klart, PI. Grunden til at dine resultater bliver lidt skæve er at PI ikke er vildt præcis!
Avatar billede loke-liscom Nybegynder
25. september 2002 - 23:31 #14
Jeg har prøvet at regne det hele med en mere præcis PI værdi. 3,1415926535897932384626433832795
Delphi's PI = 3,14159265358979
Det giver dette resultat:
-1,35525271560688E-19 = -0,000000000000000000135525271560688
Avatar billede r.hegaard Nybegynder
26. september 2002 - 08:41 #15
Jeg har prøvet og regne med følgende funktion:
procedure TRegner.CosKnapClick(Sender: TObject);
var
  pi2, taludregn: extended;
begin
  pi2:= 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196;
  taludregn:= Cos(StrToFloat(TalEdit.Text)*pi2/180);
  TalEdit.text:= FloatToStr(taludregn);
end;

Der giver den stadig 6,12303176911189E-17.
Det er der ikke noget at gøre ved, jeg må indfinde mig med det som det er........
Avatar billede hermandsen Juniormester
04. oktober 2002 - 22:47 #16
Hvor er hjælpen da bare genial! :)

Hvis du søger på Real types, så finder du ud af følgende:

Type    Range    Significant digits    Size in bytes
Extended    3.6 x 10^–4951 .. 1.1 x 10^4932    19–20    10

I følge min Engelsk-Dansk ordbog, så er "significant digits (i edb) betydende cifre". Altså får du en afrunding på den pi2-variabel du selv sætter på 19-20 cifre...
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