Support Forum

[Frage] Bitte um Hilfe bei der Fehlersuche: Rundungsfehler im Smartpart [Gelöst]

Schlagworte:
  • SmartPart

Hallo!

Ich suche seit 2 Stunden den Fehler in einer Rundungsfunktion, die den Parameter "fl" auf 2 Nachkommastellen abrunden soll, und hoffe jetzt auf Euer Schwarmwissen:

! Quadratmeter-Angaben formatieren
FUNC qmeter ( fl , dtz ) 
   fl_str = STR ( INT ( fl * 100 ) / 100 , 8 , 2 ) 
   fl1 = STRSUB ( fl_str , 1 , STRSTR ( fl_str , "." ) - 1 ) 
   fl2 = STRSUB ( fl_str , STRLEN ( fl1 ) + 2 , 2) 
   IF dtz = "punto" THEN !Punkt oder Komma als Dezimatrennzeichen
      fl_str = fl1 + "." + fl2 + " m²" 
   ELSE 
      fl_str = fl1 + "," + fl2 + " m²" 
   ENDIF 
   RETURN fl_str 
FUNC_END 

Wenn "fl" z.B. 55,71 beträgt, wird der korrekt gerundete Wert (55,71) ausgegeben, bei 65,71 wird jedoch auf 65,70 abgerundet.
Auch 131,42 wird fälschlicherweise auf 131,41 reduziert.

Hat irgendjemand eine Idee, wo der Fehler steckt? Oder vielleich einen Tip, wie man das eleganter lösen könnte?

Vielen Dank schonmal,
Stefan

GEA Arquitectos S.L.P.
Calle Gerardo Diego 6A | 41013 Sevilla | Spain

Lösung anzeigen Lösung verbergen

Hello Stefan,

ROUND_INT rounds the value.
And STR rounds the value too.

You can try also something like this:

fl = 65.7099999999999937
fl_str1 = STR ( fl - FRA ( fl ) , 1 , 0 )
fl_str2 = STR ( FRA ( fl ) * 100 , 1 , 0 ) 
fl_str3 = fl_str1 + "." + fl_str2
The result of fl_str3 is 65.71


Hallo Stefan,

I have encountered this problem before. No one has ever been able to find a solution. It must be in the source code of the SmartPart program.
The solution I adopted is to use ROUND_INT and not INT.
I would write your example like this:

fl_str = STR ( ROUND_INT ( fl * 100 ) / 100 , 3 , 2 )
I put "3" because it's just 1 character more than the number of decimals and it avoids having white spaces in front of the number with TEXT2 when the integer part has less than 6 characters.
___________

Ich bin diesem Problem bereits begegnet. Bisher konnte niemand eine Lösung finden. Es muss im Sourcecode des SmartPart-Programms stehen.
Meine Lösung ist, ROUND_INT und nicht INT zu verwenden.
Ich würde dein Beispiel so schreiben:

fl_str = STR ( ROUND_INT ( fl * 100 ) / 100 , 3 , 2 )
Ich schreibe "3", weil das nur 1 Zeichen mehr ist als die Anzahl der Dezimalstellen und es verhindert, dass man mit TEXT2 weiße Leerzeichen vor der Zahl hat, wenn der ganzzahlige Teil weniger als 6 Zeichen hat.


Guten Morgen und vielen Dank, Bertrand!

Leider hilft mir ROUND_INT nicht weiter, weil ich ja abrunden möchte.
Ich habe versucht mit Hilfe von FRA und ROUND_INT eine Abrundungsfunktion zu scripten und dabei festgestellt, dass auch FRA unpräzise Ergebnisse liefert.

Daraufhin habe ich folgendes getestet:

fl = 65.71
TEXT2 0 , -1 , STR(fl,20,20)

Das Ergebnis dieser Operation ist überraschenderweise 65.7099999999999937!

Der Smartpart-Parser scheint intern eine leichte Abweichung in den hintersten Nachkommastellen zu verursachen, was im Falle einer Abrundung zu Fehlern führt.

Auch wenn die Abweichung marginal ist, sollte so etwas eigentlich nicht vorkommen, oder?
Falls jemand aus der Entwicklung mitliest, bitte mal überprüfen...

lg,
Stefan

(Allplan 2021-1-12, Smartpartscript 2019-1)

GEA Arquitectos S.L.P.
Calle Gerardo Diego 6A | 41013 Sevilla | Spain

Anhänge (1)

Typ: image/png
25-mal heruntergeladen
Größe: 15,99 KiB

Hello Stefan,

ROUND_INT rounds the value.
And STR rounds the value too.

You can try also something like this:

fl = 65.7099999999999937
fl_str1 = STR ( fl - FRA ( fl ) , 1 , 0 )
fl_str2 = STR ( FRA ( fl ) * 100 , 1 , 0 ) 
fl_str3 = fl_str1 + "." + fl_str2
The result of fl_str3 is 65.71


I checked the result of the STR function. If you use 13 decimal places, it's fine.
So limit your values to less than 13 decimal places... I think that's enough for our construction field.


@Stefan
Intern zur Berechnung werden Fließkommazahlen gemäß IEE 754 verwendet. Da die Anzahl der zur Verfügung stehenden binären Nachkommastellen vorgegeben und damit begrenzt ist, lässt sich mit der binären Darstellung keine beliebige Genauigkeit erreichen, sondern der dezimale Wert wird oft nur näherungsweise erreicht.

Erläuterungen zur Binäten Zahlendarstellung

Website zum Testen von Fließkommazahlen

Wenn man in dieser Webseite dein Zahl 65.71 eingibt, kommt das: (s. floating_point.png)

Es ist also kein Fehler, sondern ganz Normal!

Anhänge (1)

Typ: image/png
35-mal heruntergeladen
Größe: 30,22 KiB

Hi Nemo,

Thank you for this information. So, contrary to what I wrote in my first post, everything is normal and logical.
It seemed to me that there could be a logical explanation for these variations. At least I understand now where it comes from.
Thanks for the links, especially Float Exposed.


Vielen Dank an Bertrand für das verbesserte Rundungsscript und an Nemo für das hochinteressante Hintergrundwissen.
Man lernt halt nie aus :-)

GEA Arquitectos S.L.P.
Calle Gerardo Diego 6A | 41013 Sevilla | Spain