Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Teilen (https://www.delphipraxis.net/121642-teilen.html)

SirThornberry 1. Okt 2008 20:54

Re: Hilfe
 
Hallo TimoB, gib deinem Beitrag bitte einen aussagekräftigen Titel entsprechend den Forenregeln :-)

TimoB 1. Okt 2008 21:29

Re: Teilen
 
sorry wegen derm themenbezeichnung.
das round (zahl - 0,5) kann mir auch nicht weiterhelfen. z.b. 0,99999955 -0,5 = 0,49999955 und damit auch 0

SirThornberry 1. Okt 2008 21:46

Re: Teilen
 
der neue Titel ist ja auch nicht gerade grob das Problem beschreibend :roll: Aber wenigstens war der Wille vorhanden?!

taaktaak 1. Okt 2008 22:08

Re: Teilen
 
Ich begreife nicht ganz, was hier so schwer fällt.
Und insbesondere nicht, warum du es nicht mit Format() versuchst!

Also, hier mal ein Beispiel
Delphi-Quellcode:
label1.caption:=floattostr(3.7/3.7);             // label zeigt 1
 label2.caption:=floattostr(3.7/3.70101010);      // label zeigt 0,9997270....
 label3.Caption:=format('%2.0f',[3.7/3.70101010]) // label zeigt 1
Abgesehen davon, dass 3.7 / 3.7 tatsächlich 1 ergibt, kann mit Format() dein Rundungsproblem gelöst werden :warn:

Korrekter, als den Rundungsfehler am Ende zu korrigieren, wäre es, die Berechnung schrittweise durchzugehen und die Zwischenergebnisse zu überprüfen. Vielleicht muss ja ein krummer Wert 'rauskommen, vielleicht aber auch nicht.

Gute Nacht für Heute

BUG 1. Okt 2008 22:12

Re: Hilfe
 
Zitat:

Zitat von Phoenix
Auf ganze Zahl abrunden: Round(Zahl - 0.5);

Was dann wieder trunc entspricht.

@Topic:

IMHO liegt das ganze an der Ungenauigkeit der Gleitkommazahlen. Wenn sich 3,7 mit dem Datentyp nicht genau darstellen lassen, kommt eben auch nicht 1 heraus.

2 mögliche Lösungen:
  • Nimm eine andere Einheit z.B. Millimeter und rechne mit Ganzzahlen.
  • Addiere vor dem Abrunden einen Toleranzwert (1 mm oder weniger [einfach mal probieren]).
Evtl. könnte es bei Lösung zwei auch nützlich sein, einen anderen Datentypen mit höherer Genauigkeit, z.B. Double oder Currency zu wählen, wenn der Toleranzwert möglichst klein sein soll.

[edit]Aber taaktaaks Lösung ist einfacher und vermutlich die passende für dein Problem.,gibt aber im manchen Fällen, z.B. 2.25, Kommazahlen aus, nicht wie sinnvollerweise gefordert, Ganzahlen.[/edit]

MfG,
Bug

Medium 2. Okt 2008 00:02

Re: Teilen
 
Zitat:

Zitat von taaktaak
Delphi-Quellcode:
label1.caption:=floattostr(3.7/3.7);             // label zeigt 1

Ich gehe stark davon aus, dass der Compiler die Literale bereits zur Compiletime optimiert, und zusätzlich rechnet der TE noch zuvor mit seinen Werten herum. Er hat ja nicht 3.7 als Literal im Code, und auch keine Variablen denen er beiden je direkt diesen Wert zuweist, sondern es ist ein Ergebnis einer Rechnung, und diese kann durch die Funktionsweise von Floats bereits ungenau sein, und dies zieht sich dann eben durch.
Das ist einfach nur wieder ein Fall von "kenne deine Typen, und wisse um ihre Schwächen" ;). Wenn es auf hundertprozentige Genauigkeit ankommt, kommst du um Ganzzahltypen nicht herum. Man büßt dafür allerdings die maximale Anzahl der Nachkommastellen ein, und handelt sich sobald mehr als nur Addieren/Subtrahieren vor kommt erneut Fehler durch die nötige Rundung ein.
Manchmal ist es aber auch schon genug, die Rechnungen umzustellen, anders zu klammern, und generell Operatoren zu minimieren. Ob und wo das reicht ist aber von Fall zu Fall sehr unterschiedlich.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:19 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz