![]() |
Delphi-Version: 2010
Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Hallo zusammen,
ich steh gerade total auf dem Schlauch und kann mir den folgenden Fehler nicht erklären:
Delphi-Quellcode:
procedure Test(min, max : Double);
var x : Integer; a, b : Double; begin x := Ceil(Log10(max)) - Floor(Log10(min)) + 1; WriteLn(x); a := Log10(max); b := Log10(min); x := Ceil(a) - Floor(b) + 1; WriteLn(x); end; begin Test(1e-2, 1e8); Test(1e-2, 1e7); Test(1e-2, 1e6); end.
Code:
Die Ausgabe sollte natürlich sein:
11
11 11 10 9 9
Code:
11
11 10 10 9 9 |
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Was passiert, wenn du den Variablen a und b den Datentyp Extended gibst?
|
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Code:
Jetzt bin ich noch verwirrter.
11
11 11 11 9 9 |
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Ich weiß nicht, ob es hilft, aber guck auch mal hier:
![]() |
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Zitat:
|
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Naja, ich hab mir Dein Problem nur kurz angeguckt -ist ja nicht mein Problem:wink:.
Aber ich weiss, dass in amath einige Fehler von math ausgeräumt wurden, auch Rundungsprobleme. Vielleicht fällt das bei Dir ja auch darunter. Ausprobieren bzw gucken muß Du aber selbst, oder es lassen. |
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Ich glaub du hast meine Antwort falsch verstanden. Ich meinte ich habe zwar nicht nachvollzogen, ob das hier mit dem Thread zusammenhängt, aber ich bin absolut geschockt. Hab mich zwar inzwischen daran gewöhnt, ab und zu mal einen halben Tag wegen irgendwelchen blöden Delphi Bugs zu verschwenden, aber dass solche elementaren Dinge seit 15 Jahren so falsch sind, ist ja echt krass.
|
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Zitat:
Code:
Versuche mal folgendes: Delphi neu starten, Programm neu kompilieren und wenn das nicht reicht: Rechner neu starten.
namespace Test_Rundung
{ class Program { static void Test(double min, double max) { int x; double a; double b; x = Convert.ToInt32(Math.Ceiling(Math.Log10(max))) - Convert.ToInt32(Math.Floor(Math.Log10(min))) + 1; Console.WriteLine(x); a = Math.Log10(max); b = Math.Log10(min); x = Convert.ToInt32(Math.Ceiling(a)) - Convert.ToInt32(Math.Floor(b)) + 1; Console.WriteLine(x); } public static void Main(string[] args) { Console.WriteLine("Hello World!"); Test(1e-2, 1e8); Test(1e-2, 1e7); Test(1e-2, 1e6); Console.Write("Press any key to continue . . . "); Console.ReadKey(true); } } } Bernhard PS: Die Einrückung der Forensoftware ist wieder brutal toll. |
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Ich hatte den gleichen Test auch vorher mit vc und gcc gemacht. Aber da gibt ceil und floor ja (wie c#) eine Fließkommazahl zurück, daher dachte ich, ich würde bei Delphi irgendwas übersehen.
|
AW: Ceil Floor Log10 - Rundungsfehler, Überlauf o.ä. (?)
Deine Idee ist zwar ein Disaster-Konzept, weil Differenzen von zwei Sprungfunktionen geradezu danach schreien, solche Effekte hervorzurufen; in Deinem Fall für Werte, die keine Zehnerpotenzen sind.
Interessant ist jedoch an Deinem Problem folgendes: Es sieht so aus als wenn Du auf eine Inkonsistenz der FPU gestoßen bist. log10(x) wird im Prinzip als log10(2)*log2(x) berechnet. Wenn man das so programmiert, verschwindet auch Dein Problem. Etwas mehr Hintergrund-Info nach einiger Knobelei:
Delphi-Quellcode:
Die beiden Funktionen sollten eigentlich dieselben Ergebisse bringen, log10(x) rechnet log10(2) * log2(x) via FPU-Befehl fyl2x und log10a(x) rechnet (1*log2(x)) * log10(2). Für x=1e7 rechnet log10a richtig und log10 (die Delphi-Implementation) um 1 ulp zu hoch (die $-Zahlen sind die internen extended Darstellungen via AMath und MPArith)
{---------------------------------------------------------------------------}
function log10(x: extended): extended; assembler; {-Return base 10 logarithm of x} asm fldlg2 fld [x] fyl2x fwait end; {---------------------------------------------------------------------------} function log10a(x: extended): extended; assembler; {-Return base 10 logarithm of x} asm fld1 fld [x] fyl2x fldlg2 fmul end;
Code:
Gruß Gammatester
log10a(1e7) = $4001E000000000000000 = 7.0
log10(1e7) = $4001E000000000000001 = 7.00000000000000000043368086899420177360298112034797668457031 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz