victurus Skrevet 2. august 2007 Rapporter Del Skrevet 2. august 2007 (endret) Hei, Har støtt på noe av det særeste. Jeg har en variabel som er av typen double. Den sammenligner jeg mot en annen variabel som er en streng (som parses). Ved sammenligning får jeg opp at disse ikke er like (selvom de er det). Boolean svar = false; double beregning = 0; try { beregning = double.Parse(kunde[5]) + double.Parse(kunde[6]) - double.Parse(kunde[8]) + double.Parse(kunde[17]); } catch { logg.Write("[ ] Feil ved parsing av tall"); } if (beregning == double.Parse(kunde[9])) { svar = true; }//endif else { logg.Write(beregning.ToString()+" ikke lik "+ double.Parse(kunde9])); } logg.Write("[ ] \t Kontosammendrag kontrollert"); logg.Write(svar.ToString()); return svar; resultatet i loggen er dette: ... 8824,97 ikke lik 8824,97 ... Legg også merke til siste if setningen. Hvis jeg endrer beregning til dette: double.parse(beregning.ToString()) //altså jeg gjør double->streng->double dvs if(double.Parse(beregning.ToString()) == double.Parse(kunde[9])) Så går det?! ?-Men hvorfor i allverden ?? Victurus! *edit : fjernet litt kode får å få det oversiktlig Endret 2. august 2007 av victurus Lenke til kommentar
victurus Skrevet 3. august 2007 Forfatter Rapporter Del Skrevet 3. august 2007 har nå sittet og fundert mye på dette. Sjekk denne koden: double test = 8824.97; double test2 = 0 + 8638.4500000000000 + 220.2900000000000 + 0 - 33.7700000000000 - 0 - 0; if (test == test2) { Console.WriteLine("OK!"); } Denne går jaggu ikke... Victurus! Lenke til kommentar
Manfred Skrevet 3. august 2007 Rapporter Del Skrevet 3. august 2007 decimal test = 8824.97M; decimal test2 = 0M + 8638.4500000000000M + 220.2900000000000M + 0M - 33.7700000000000M - 0M - 0M; if (test.Equals(test2)) { Response.Write("OK!"); } else if (test < test2) { Response.Write(test.ToString() + " er mindre enn " + test2.ToString()); } else if (test > test2) { Response.Write(test.ToString() + " er større enn " + test2.ToString()); } else { Response.Write(test.ToString() + " er ikke lik " + test2.ToString()); } Resultat: OK! Endret til decimal i stedet for double, og da funka det. Lenke til kommentar
GeirGrusom Skrevet 3. august 2007 Rapporter Del Skrevet 3. august 2007 Dette kan ha noe med at float og double er ganske unøyaktige, når man gjør om en string til double, vil den gjøre om til den verdie nærmest som passer, altså kan man få litt forskjellige resultater hver gang. IEEE sin flyttall, 80-bit, er laget for å rette litt på dette, men blir ikke brukt av noen programmeringsspråk jeg kjenner, bortsett fra assembly da. decimal tar det enda litt lenger. Derfor kan det fungere i decimal, men ikke i double eller float, avhenger av presisjonen din. Lenke til kommentar
victurus Skrevet 3. august 2007 Forfatter Rapporter Del Skrevet 3. august 2007 Takk for respons! Du har rett, det fungerer med decimal. -Men synes dog at det er rart at double tryner så hardt, på såpass små tall. ta dette eks. double test6 = 1823.96+7001.01; double test7 = 8824.97; Går ikke.. men endrer jeg test6 til: 7823.96+1001.01 så går det.. Men jeg får endre alt i koden til decimal, så ting fungerer hvertfall. Takk manfred Victurus! Lenke til kommentar
Manfred Skrevet 3. august 2007 Rapporter Del Skrevet 3. august 2007 Så langt jeg kunne lese så har nok GeirGrusom rett her. Presisjonen på en double eller en float er ikke nødvendigvis den største. Mulig du kunne styret litt frem og tilbake med diverse funksjoner i System.Math, men jeg synes liksom det var hakket enklere å da bare bruke decimal i stedet. Lenke til kommentar
victurus Skrevet 3. august 2007 Forfatter Rapporter Del Skrevet 3. august 2007 Dette kan ha noe med at float og double er ganske unøyaktige, når man gjør om en string til double, vil den gjøre om til den verdie nærmest som passer, altså kan man få litt forskjellige resultater hver gang.IEEE sin flyttall, 80-bit, er laget for å rette litt på dette, men blir ikke brukt av noen programmeringsspråk jeg kjenner, bortsett fra assembly da. decimal tar det enda litt lenger. Derfor kan det fungere i decimal, men ikke i double eller float, avhenger av presisjonen din. Men det jeg stusser på er hvordan den kan summere ut alt og gi svaret med like mange siffer men samtidig påstå at dem ikke er like? Victurus! Lenke til kommentar
Peter Skrevet 4. august 2007 Rapporter Del Skrevet 4. august 2007 Dette er et problem i alle språk. F.eks.: float f1 = 0.1; float f2 = 0.1; Her vil man anta at f1 == f2, men det er altså ikke nødvendig vis tilfellet pga. grunner som det er skrevet store avhandlinger om. Ihvertfall, det man ofte gjør når man skal sammenligne to flyttall er å si hvor store forskjeller man kan godta og fortsatt si at tallet er likt. eks. float f1 = 0.001 float f2 = 0.001 if( f2 - f1 < 0.0001 || f1 - f2 < 0.0001 ) tallene er tilnærmet like Lenke til kommentar
GeirGrusom Skrevet 5. august 2007 Rapporter Del Skrevet 5. august 2007 jeg skrev en helper klasse for dette Klikk for å se/fjerne innholdet nedenfor /// <summary> /// DoubleCompare is a helper class to compare double precisiion floating point values. /// It contains a tolerance field wich contains the precision of tolerence. /// This is only applied to the Equals functions == and != /// FloatCompare can be on either side of the comparison. /// </summary> /// <example> /// if(new DoubleCompare(128.021312f) == double.Parse("128.021312")) /// MessageBox.Show("Equals!"); /// </example> public struct DoubleCompare { private double m_tolerence; private double m_value; public double Tolerence { get { return m_tolerence; } set { m_tolerence = value; } } public override int GetHashCode() { return m_value.GetHashCode() ^ m_tolerence.GetHashCode(); } public double Value { get { return m_value; } set { m_value = value; } } public DoubleCompare(double value) { m_value = value; m_tolerence = 0.0001f; } public DoubleCompare(double value, double tolerance) { m_value = value; m_tolerence = tolerance; } public override bool Equals(object obj) { if (obj is DoubleCompare) { return (m_value - ((DoubleCompare)obj).m_value) < m_tolerence; } else if (obj is double) { return m_value - (double)obj < m_tolerence; } return false; } public static bool operator ==(DoubleCompare a, DoubleCompare b) { return (a.m_value - b.m_value) < a.m_tolerence; } public static bool operator ==(DoubleCompare a, double b) { return (a.m_value - b) < a.m_tolerence; } public static bool operator ==(double a, DoubleCompare b) { return (a - b.m_value) < b.m_tolerence; } public static bool operator !=(DoubleCompare a, DoubleCompare b) { return !((a.m_value - b.m_value) < a.m_tolerence); } public static bool operator !=(DoubleCompare a, double b) { return !((a.m_value - b) < a.m_tolerence); } public static bool operator !=(double a, DoubleCompare b) { return !((a - b.m_value) < b.m_tolerence); } public static implicit operator float(DoubleCompare a) { return (float)a.m_value; } public static implicit operator double(DoubleCompare a) { return a.m_value; } public static explicit operator int(DoubleCompare a) { return (int)a.m_value; } public override string ToString() { return m_value.ToString(); } public string ToString(IFormatProvider provider) { return m_value.ToString(provider); } public string ToString(string format) { return m_value.ToString(format); } public string ToString(string format, IFormatProvider provider) { return m_value.ToString(format, provider); } } Lenke til kommentar
alftore Skrevet 5. august 2007 Rapporter Del Skrevet 5. august 2007 (endret) Hva med å bruke Money klassen? Edit: Nevermind, ser at den ikke finnes. Blandet nok med SQL Server. Merkelig at ikke .NET har noe tilsvarende. Når jeg har jobbet med økonomi så har jeg alltid lagret tallene som en integer. Bare laget en regel på at de to siste sifferene er øre. Eks. 1122 = 11,22 kr http://www.michaelbrumm.com/money.html Endret 5. august 2007 av alftore Lenke til kommentar
GeirGrusom Skrevet 5. august 2007 Rapporter Del Skrevet 5. august 2007 (endret) Decimal erstatter Money. Edit: Visual Basic 6.0 støttet en datatype som het Currency, men etter det jeg har forstått, er det ingen reell forskjell mellom Currency og Decimal Decimal er 128-bit, som skal være nok til å behandle alle verdens statsbudsjett kombinert. edit2: etter nærmere gjennomgang, er Money datatypen til SQL Server også 128-bit, så da er det ingen tekniske forskjeller mellom dem. Endret 5. august 2007 av GeirGrusom Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå