12. november 2002 - 19:44Der er
14 kommentarer og 1 løsning
Problemmer med sinus
Howdy eksperter... Jeg har et problem jeg har grublet længe over, og ikke helt kan finde en logisk løsning på... Jeg har lavet et program til at udregne sin, cos og tan (også i invers) både i radianer (som vb normalt regner i) og grader. Problemmet er bare at min funktion ved sinus (ikke invers) giver et forkert resultat ved ca. 5 decimal (hvor samme resultat i radianer er ok). Måske er det blot en afrundingsfejl, men jeg smider lige min brugte kode ind, for at nogle friske øjne måske kan spotte min fejl... Jeg har lavet en dll-fil med matematik-funktionerne som jeg så refererer til fra mit program:
[Fra dll-filen] Const Pi As Double = 3.14159265358979
Public Function ArcSin(Tal As Single, Optional Radianer As Boolean = True) As Single Dim Resultat As Single, Grader As Single
If Tal = 1 Then Resultat = Pi / 2 Else Resultat = Atn(Tal / Sqr(-Tal * Tal + 1)) End If If Radianer = True Then ArcSin = Resultat Else Grader = Replace(Resultat, ".", ",") ArcSin = RadTilGrad(Resultat) End If End Function
Public Function RadTilGrad(Radianer As Single) As Single RadTilGrad = Radianer * (180 / Pi) End Function
Public Function GradTilRad(Grader As Single) As Single GradTilRad = Grader * (Pi / 180) End Function
[Fra selve programmet] If Invers = True Then 'Invers: Grader = MAT.ArcSin(Tal, False) 'False retunere gradantallet - se funktionen i dll-filen Radianer = MAT.ArcSin(Tal) Else 'Ikke invers: Grader = MAT.GradTilRad(Sin(Tal)) Radianer = Sin(Tal) End If
Støv, fibre og metalliske partikler kan påvirke både uptime, levetid og driftssikkerhed. Derfor arbejder flere datacentre systematisk med contamination control.
Har du prøvet at sikre dig, at enhver beregning internt i ArcSin, RadTilGrad og GradTilRad foregår i Double, altså så du flytter enhver Single-parameter over i en lokal Double-variabel og regner med denne, og først til sidst flytter det færdige resultat tilbage i en Single, som du returnerer?
Nej, alle mine variable er af typen Single... Dog på nær konstanten Pi, som jeg prøvede at ændre viabel-type på, så jeg måske kunne få flere decimaler med... dog uden noget held :(
Tjo, men jeg kan ikke helt se hvad det gavner - Single-variablen kan da rumme ligeså mange (vist også lidt flere) cifre og decimaler en double... Jeg vil gerne teste det, men kan du så ikke lige forklarer hvad forskellen er?
Se følgende macro til VBA /Excel, jeg har konstrueret til formålet:
Dim sglVar1 As Single Dim sglVar2 As Single Dim dblVar1 As Double Dim dblVar2 As Double sglVar1 = 8 dblVar1 = 8 sglVar2 = 3 dblVar2 = 3 Range("B1").Select ActiveCell.FormulaR1C1 = sglVar1 / sglVar2 Range("B2").Select ActiveCell.FormulaR1C1 = dblVar1 / dblVar2
resultatet bliver:
B1 = 2,66666674613952 B2 = 2,66666666666667
Se - hvordan den når frem til det besynderlige resultat i B1 ved jeg ikke, det burde være 2,6666667 uden resten af de mystiske decimaler. De samme pudsigheder har jeg til tider stødt på i VB, så jeg bruger nu doubles altid. Jeg er ganske sikker på, at gør du det samme (skifter alle singles til doubles), så virker det - jeg vil vædde en sneøl ;o)
PS: Lægger man mærke til navnene på de to typer, afsløres det, at en double er større end en single ;o) (single = 4 bytes, double = 8 bytes)
Det forklare dog stadig ikke efter min mening det med de ekstra forkerte decimaler i mit eksempel - men det svarer på dit spørgsmål fra 12/11-2002 21:54:38
Det ser da rigtig godt ud martin_moth, og ligner også at det er der mit problem ligger, men.... jeg er sq bange for at du skylder mig en sneøl :) Jeg har udskiftet ALLE single's til double - både i dll-filen og i mit program, men lortet vil stadig ikke spytte det rigtige resultat ud... Ved ikke helt hvorfor det stadig ikke virker *snøft*
Jeg har lige efterprøvet din kode fra exel, med følgede kode:
Dim Res1 As Single, Tal11 As Single, Tal12 As Single Dim Res2 As Double, Tal21 As Double, Tal22 As Double Tal11 = 8 'Single Tal12 = 3 'Single Tal21 = 8 'Double Tal22 = 3 'Double Res1 = Tal11 / Tal12 'Single: 2,666667 Res2 = Tal21 / Tal22 'Double: 2,66666666666667
'Res1' og 'Res2' giver i VB det samme resultat - bare med et forskelligt antal decimaler. Fatter ikke helt hvordan det hænger sammen at dit resultat afviger..
Hmmm - det ser ikke godt ud - bare for eksperimentets skyld, hvis du dim'mer dem uden type (altså "Dim Resultat" i stedet for "Dim Resultat As Single") - bliver det så bedre? Hvis ja, så kan vi måske "regne baglæns" og finde fejlen... Du får lige en Albani jylebryg som lovet: www.kdj-design.dk/baggrunde/001.html
Hehe... mange tak for pilzen - den er dæjlme dejlig!! :} Jeg lige testet dit foreslag, og resultatet var det samme antal decimaler som ved Double (gav også det rigtige resultat)... Det er sq m*e*g*e*t mystisk
Jeps, det er snart nisse-tid, og det er således dem der får pointene i denne omgang.
Synes godt om
Ny brugerNybegynder
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.