Hallo,
ich benötige und erstellte - dachte ich - eine Funktion, welche den Nachkommawert einer beliebigen Zahl auf x.5 ändert.
Aus z.B. 1.0 bis 1.9 einschließlich soll 1.5 werden. Ebenso aus z.B. -1 bis -1.9 soll -1.5 werden.
Meine Funktion:
float toPointFive(float wert)
{
int x = (int) wert;
if (wert < 0.0f)
{
x = Math.Abs(x);
wert = x + 0.5f;
wert = wert * -1f;
}
else
{
wert = x + 0.5f;
}
return wert;
}
Bei allen negativen Zahlen mit .0 als Nachkommastelle tritt ein Fehler auf.
Aus -3.0 wird nicht, wie gewünscht, -3.5 sondern -2.5, aus -2.0 wird -1.5.
-3.1 bis -3.9 werden zu -3.5, nur -3.0 nicht.
Habt Ihr eine Idee, woran das liegen mag?
Ich weiß jedenfalls nicht mehr weiter.
Vielen Dank für Eure Hilfe.
Magst Du dem Forum auch den Fehler verraten, oder sollen wir raten?
[Hinweis] Wie poste ich richtig? Punkt 5
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Schau bitte nochmal in meinen Beitrag, dort findest du meine Frage.
>> Aus -3.0 wird nicht, wie gewünscht, -3.5 sondern -2.5<<
Dann passt die Formulierung "tritt ein Fehler auf" nicht.
Offenbar also nur ein logischer Fehler, den Du dann problemlos via Debugging selbst finden kannst.
[Artikel] Debugger: Wie verwende ich den von Visual Studio?
Siehst ja dann, wo Du ein .5 erwartest aber was anderes raus kommt.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Laß dir den Wert von x
mal anzeigen - s.a. [FAQ] Double und Float: Fehler beim Vergleich und Rundungsfehler. Durch Rundungsfehler kann hier aus Werten nahe bei -3.0 (intern also -2.9xxx) dann -2 werden.
Wie rufst du denn die Methode aus? Wenn du z.B. eine Schleife mit wert += 0.1f
verwendest, dann hast du schon per se einen Rundungsfehler drin.
Entschuldige, aber
a) hast du meinen Beitrag komplett verstehend gelesen?
b) willst du mich hier nur maßregeln oder kommt noch etwas konstruktives von dir?
In der Überschrift steht ein (?) hinter "Fehler".
Den offenbar logischen Fehler finde ich ja eben nicht, sonst würde ich hier bestimmt nicht schreiben, weil, Zeit ist Geld.
Ausgabe sagt: wert = -3.0 und wird zu -2.5 anstatt, wie logischerweise erwartet, -3.5.
So.
Klar genug?
Für würdig befunden, darüber nachzudenken?
Den Code mal selbst ausführen?
Eine Idee?
Danke.
Danke, Th69, das ist eine sinnvolle Antwort.
Werde ich gleich überprüfen.
Danke sehr.
Den offenbar logischen Fehler finde ich ja eben nicht, sonst würde ich hier bestimmt nicht schreiben, weil, Zeit ist Geld.
Wenn Du Dich ordentlich ausdrücken würdest, hätte man auch verstanden, was Du meinst.
Du hast deutlich von "es tritt ein Fehler auf" gesprochen, was nicht der Tatsache entspricht.
Es ist nichts anderes als ein logischer Fehler: es kommt nicht das raus, was Du erwartest.
Das ist aber alles andere als "ein Fehler, der auftritt".
Selbstverständlich kannst Du - wie Du es hier deutlich zeigst - grundreizend antworten.
Das Resultat ist verständlicherweise: Ablehnung. Die Leute werden Dir weniger antworten - Zurecht.
Auch meine Zeit ist was wert - trotzdem hab ich sie mir genommen, um zu antworten und Dir zu helfen.
Es war eine Nachfrage, was der Fehler ist, weil Du Dich entsprechend undeutlich ausgedrückt hast.
Den Code mal selbst ausführen?
Das ist nicht die Aufgabe eines Forums.
Wenn Du denkst, dass Du das Debugging auf das Forum abwälzen kannst, dann haste Dich halt einfach geschnitten. Auch die Helfer verwenden Zeit, die was wert ist.
So läuft das hier nicht. So läuft das prinzipiell in keinem Forum.
Daher steht dies auch ausdrücklich in den Regeln, auf die ich Dich aufmerksam gemacht habe. Auch in anderen Foren.
Denn dieser Fehler hier, ein logischer Fehler, kannst Du selbst rausfinden.
Auch den von Th69 genannten Rundungsfehler wirste per Debugging herausfinden können; er hat Dich inhaltlich damit ebenfalls auf eigenes Debugging hingewiesen.
Ein Forum dient auch der Hilfe zur Selbsthilfe. Wenn Du das in der Form nicht akzeptierst, und lieber Helfer bepöbelst, die ihre eigene wertvolle Zeit verwenden, um Dir zu helfen, dann biste halt an der Adresse falsch.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hi,
also um ehrlich zu sein - ich hab deinen Code auf SharpLab mal getestet - bei mir kommt bei Eingabe -3.0 auch korrekt -3.5 raus.
Sicher, dass du den aktuellen Build prüfst?
LG
Hallo Taipi88,
Th69 wies mich darauf hin, dass die Benutzung in einer Schleife der Art =+ 0.1f grundsätzlich einen Rundungsfehler beinhalten würde.
Genau dies tat ich, allerdings nur zu Testzwecken.
Ich benutze eine ähnliche Routine wie die hier aufgelistete in UNITY, um Objekte zur Laufzeit korrekt zu positionieren beziehungsweise ihre Position zu korrigieren.
Dabei fiel mir auf, dass ein Objekt sich auf z.B. 1.4 und dann auf 2.4 befand, was nicht sein sollte und durfte.
Ich untersuchte diesen Sachverhalt näher und kam zu keiner Lösung.
In meiner Not schrieb ich die oben aufgelistete Routine und nutzte diese in UNITY und stieß auf -3.0 wird zu -2.5 und war daraufhin vollends verwirrt und bat hier um Klärung.
Ich werde mich wohl näher mit dem Umgang von C# mit floats und Runden befassen müssen.
Darauf wäre ich, obwohl naheliegend, so schnell nicht gekommen.
Den Wald vor lauter Bäumen nicht finden...
Danke sehr für deine Hilfe.
Wenn Du Dich ordentlich ausdrücken würdest, hätte man auch verstanden, was Du meinst.
Seltsam, Th69 hat sofort verstanden worum es geht und mir einen Lösungsansatz an die Hand gegeben.
Nochmal, bei manchen geht es wohl nicht so schnell, ich schrieb extra hinter Fehler ein Fragezeichen.
Für mich war es in diesem Kontext ein Fehler, da das Resultat nicht wie erwartet ausfiel.
Google Fehler und staune.
Ein logischer Fehler wäre es gewesen, wenn ich in meinem Code etwas "falsch" = unlogisch geschrieben hättte, zum Beispiel - man beachte das "zum Beispiel" und nagle mich nicht darauf/deswegen fest - die Operation mit X ohne das vorherige Abs(x) aufzurufen.
Das wäre ein logischer Fehler gewesen.
Dieser "Fehler" wurde aber, wie ich Dank Th69 nun erfuhr, nicht von mir begangen, sondern liegt an C# und seinem Umgang mit floats.
So weit ich es überblicke, habe ich nicht gepöbelt, wie du es fälschlicherweise auszudrücken beliebtst, sondern mich mokiert.
Nur über dich. Über niemand sonst.
Über deine Nichthilfe und dein aufgeblähtes Gehabe.
Anstatt konkret an die Sache heranzugehen sich erstmal an Marginalitäten abzuarbeiten.
Übrigens und abschließend heißt es bist du und "halt an der falschen Adresse" und nicht "biste halt an der Adresse falsch" und du bist in diesem Thread kein "Helfer, die ich angeblich angepöbelt habe".
Soviel dazu und ich wünsche dir einen schönen Tag.
Dieser "Fehler" wurde aber, wie ich Dank Th69 nun erfuhr, nicht von mir begangen, sondern liegt an C# und seinem Umgang mit floats.
Erster Absatz von [FAQ] Double und Float: Fehler beim Vergleich und Rundungsfehler
Daher ist das Folgende kein spezifisches Problem von C#/.NET, sondern ein Problem des weit verbreiteten Standards bzw. genereller gesprochen der auf Computern zwangsläufig begrenzten Genauigkeit der Zahlendarstellung.
Wenn Dir Leute Hinweise zukommen lassen, dann les es bitte durch.
Danke.
PS: wenn Du meinst weiter zu pöbeln, dann machen wir halt dicht.
Ganz einfach.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Wenn du diese Werte als Koordinaten verwenden willst, wäre es dann nicht möglich diese per int abzubilden oder gibt z.B. Unity diese schon so vor?
Gerade wegen Rundungsfehlern, die du dann häufiger haben wirst, würde ich darauf verzichten.
Auch sollte man bei Spielen soweit wie möglich mit Ganzzahlen arbeiten, da die CPU diese schneller verarbeiten kann.
Dürfte zwar auch heute schon nicht mehr so gravierend sein, aber Performance kann man dadurch bei falscher Nutzung schon verlieren.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Auch sollte man bei Spielen soweit wie möglich mit Ganzzahlen arbeiten, da die CPU diese schneller verarbeiten kann.
Spiele und Grafiken nutzen i.d.R. float
.
Die Genauigkeit von double
wird hier i.d.R. nicht benötigt.
Geht hier weniger um die Performance, sondern eher um den Speicherverbrauch bzw. dessen Bandbreite.
Wenn Hardware (CPU) double bereits nativ unterstützt (wie zB x86) und float daher emuliert wird, ist double i.d.R. schneller.
Moderne Hardware hat dann aber SSE die wiederum beide Typen crunched (zB 4xfloat / 2xdouble in einem Zyklus).
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@Abt
Dann ist mein Wissen doch schon stark veraltet.
Ist auch ein paar Jahre her, dass ich hier ein paar kleine Spielchen programmiert habe.
Auch dürfte die CPU Leistung heute kaum noch ein Problem damit haben.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
a) Also, bis jetzt pöbelte ich nicht.
b) Ich befolge die Ratschläge von Leuten.
c) Erbsenzählerei, ob nur C#-Fehler oder allgemein einerlei.
d) Leck mich im Arsch und schieb dir diesen Thread in den selbigen.
Erbärmlicher kleiner Wichtigtuer.
MSVP? Wichser. Kleiner. Elendiger. Flachwichser.
Absolut unnötig sowas. Benutzer habe ich gesperrt.