Laden...

Fehler(?) bei der Umwandlung der Nachkommastellen einer Fließkommazahl.

Erstellt von GyrosMitVielScharf vor 4 Jahren Letzter Beitrag vor 4 Jahren 2.235 Views
Thema geschlossen
G
GyrosMitVielScharf Themenstarter:in
14 Beiträge seit 2017
vor 4 Jahren
Fehler(?) bei der Umwandlung der Nachkommastellen einer Fließkommazahl.

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.

16.806 Beiträge seit 2008
vor 4 Jahren

Magst Du dem Forum auch den Fehler verraten, oder sollen wir raten?
[Hinweis] Wie poste ich richtig? Punkt 5

G
GyrosMitVielScharf Themenstarter:in
14 Beiträge seit 2017
vor 4 Jahren

Schau bitte nochmal in meinen Beitrag, dort findest du meine Frage.
>> Aus -3.0 wird nicht, wie gewünscht, -3.5 sondern -2.5<<

16.806 Beiträge seit 2008
vor 4 Jahren

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.

4.931 Beiträge seit 2008
vor 4 Jahren

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.

G
GyrosMitVielScharf Themenstarter:in
14 Beiträge seit 2017
vor 4 Jahren

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.

G
GyrosMitVielScharf Themenstarter:in
14 Beiträge seit 2017
vor 4 Jahren

Danke, Th69, das ist eine sinnvolle Antwort.

Werde ich gleich überprüfen.

Danke sehr.

16.806 Beiträge seit 2008
vor 4 Jahren

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.

1.029 Beiträge seit 2010
vor 4 Jahren

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

G
GyrosMitVielScharf Themenstarter:in
14 Beiträge seit 2017
vor 4 Jahren

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.

G
GyrosMitVielScharf Themenstarter:in
14 Beiträge seit 2017
vor 4 Jahren

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.

16.806 Beiträge seit 2008
vor 4 Jahren

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.

T
2.219 Beiträge seit 2008
vor 4 Jahren

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.

16.806 Beiträge seit 2008
vor 4 Jahren

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).

T
2.219 Beiträge seit 2008
vor 4 Jahren

@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.

G
GyrosMitVielScharf Themenstarter:in
14 Beiträge seit 2017
vor 4 Jahren

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.

Hinweis von MrSparkle vor 4 Jahren

Absolut unnötig sowas. Benutzer habe ich gesperrt.

Thema geschlossen