Hot News:

Mit Unterstützung durch:

  Foren auf CAD.de (alle Foren)
  Lisp
  Runden von einer reellen Zahl in Gazzahl

Antwort erstellen  Neues Thema erstellen
CAD.de Login | Logout | Profil | Profil bearbeiten | Registrieren | Voreinstellungen | Hilfe | Suchen

Anzeige:

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen nächster neuer Beitrag | nächster älterer Beitrag
  
Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte
Autor Thema:  Runden von einer reellen Zahl in Gazzahl (4792 mal gelesen)
Manuel Sauter
Mitglied



Sehen Sie sich das Profil von Manuel Sauter an!   Senden Sie eine Private Message an Manuel Sauter  Schreiben Sie einen Gästebucheintrag für Manuel Sauter

Beiträge: 28
Registriert: 29.10.2003

erstellt am: 28. Jun. 2004 14:38    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Zusammen,

habe folgendes Problem! Die beiden Variablen nBelBrW1 und nBelBrW2 werden berechnet und anschließend unter einen neuen Variable in eine Ganzzahl geändert.

        (setq nBelBrW1 (- (+ nWst2 iIes ) iAes)
              nBelBrW2 (- (+ nWst1 iIes ) iAes)
              eBelBrW1 (fix nBelBrW1)
              eBelBrW2 (fix nBelBrW2)
        )

Bei der Überprüfung der Variablen nBelBrW1 und nBelBrW2 werden z.B die Werte 750.0 für beide Variablen angezeigt.
Bei der Überprüfung der Variablen eBelBrW1 und eBelBrW2 bekomme ich folgendes Ergebnis:
eBelBrW1 = 750
eBelBrW2 = 749
Es ist mir unerklärlich wie die 749 zustande kommt. Die geschieht auch nicht jedesmal bei dem Durchlauf der Routine.
Mache ich einen Fehler, oder verstehe ich den Befehl "fix" nicht richtig?
Hat jemand vielleicht mal ein ähnliches Problem?

Gruß Manuel

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Brischke
Moderator
CAD on demand GmbH




Sehen Sie sich das Profil von Brischke an!   Senden Sie eine Private Message an Brischke  Schreiben Sie einen Gästebucheintrag für Brischke

Beiträge: 4171
Registriert: 17.05.2001

AutoCAD 20XX, defun-tools (d-tools.eu)

erstellt am: 28. Jun. 2004 14:51    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Manuel Sauter 10 Unities + Antwort hilfreich

Hallo Manuel,

die Funktion fix schneidet einfach die Nachkommastellen ab. Wenn also die berechnete Zahl nicht exakt oder größer 750 ist, dann kommt es zu dieser Erscheinug. Du solltest also auch die Nachkommastellen prüfen. um dann zu entscheiden, ob auf oder abgerundet wird.
Nachkommastellen = Zahl - fix(Zahl)

Grüße Holger

------------------
Holger Brischke
(defun - Lisp over night!
AutoLISP-Programmierung für AutoCAD
Da weiß man, wann man's hat!

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Manuel Sauter
Mitglied



Sehen Sie sich das Profil von Manuel Sauter an!   Senden Sie eine Private Message an Manuel Sauter  Schreiben Sie einen Gästebucheintrag für Manuel Sauter

Beiträge: 28
Registriert: 29.10.2003

erstellt am: 28. Jun. 2004 15:16    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Holger,

ich möchte garnicht Runden, sonder nur die Nachkommastellen weg haben. In diesem Falle verstehe ich den Befehl "fix" schon richtig.
Wie oben schon geschrieben bekomme ich aber aus dem Wert 750.0, der berechnet wurde, über den Befehl "fix"  manchmal den Wert 749!
Über den Visual Lisp Editor habe ich mir immer die Werte von nBelBrW1 und nBelBrW2 anzeigen lassen. Die sind jedesmal 750.0. Die Werte eBelBrW1 oder eBelBrW2 sind aber manchmal 749. Das darf doch nicht sein, oder?

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP


Ex-Mitglied

erstellt am: 28. Jun. 2004 15:29    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat

Zitat:
Original erstellt von Manuel Sauter:
ich möchte garnicht Runden, sonder nur die Nachkommastellen weg haben.

Nein, ich glaube nicht, dass Du das wirklich willst :-)

"Reelle" Zahlen gibt's auf Computern nicht wirklich, denn zu deren Darstellung würden wir exakt unendlich viel Speicher benötigen. Statt dessen verwenden wir prinzipiell nur näherungsweise Dezimalzahlen mit endlicher Genauigkeit, und dadurch kann es nach einer Anzahl von Rechenoperationen schon mal vorkommen, dass ein Ergebnis nicht mathematisch korrekt 750.0 ergibt, sondern 749.999999999999998. Und wenn Du von 749.999999999999998 mittels FIX die Nachkommastellen abschneidest, kriegst Du auch das korrekte Ergebnis 749 raus.

Du willst also tatsächlich erst auf beispielsweise 10 Nachkommastellen runden, und willst davon erst die Nachkommastellen abschneiden.

Zitat:
Das darf doch nicht sein, oder?

Ich hoffe, Du verstehst jetzt, warum das sogar so sein MUSS.

Tom Berger

------------------


mapcar
Mitglied
CADmin



Sehen Sie sich das Profil von mapcar an!   Senden Sie eine Private Message an mapcar  Schreiben Sie einen Gästebucheintrag für mapcar

Beiträge: 1250
Registriert: 20.05.2002

Time flies like an arrow, fruit flies like a banana (Groucho Marx)

erstellt am: 28. Jun. 2004 16:12    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Manuel Sauter 10 Unities + Antwort hilfreich

http://ww3.cad.de/foren/ubb/Forum259/HTML/000271.shtml

Da ging es auch um Floats - ich habe da eine etwas längere Erklärung abgeliefert, die zum Verständnis beitragen kann, warum man beim Double eben nicht mit 14 Nachkommastellen rechnen kann, sondern nur mit 14 signifikanten Stellen überhaupt.

Gruß, Axel

------------------

Meine AutoLisp-Seiten
Meine private Homepage
Mein Angriff auf dein Zwerchfell
Mein Lexikon der Fotografie
Mein gereimtes Gesülze

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Dabrunz
Mitglied



Sehen Sie sich das Profil von Dabrunz an!   Senden Sie eine Private Message an Dabrunz  Schreiben Sie einen Gästebucheintrag für Dabrunz

Beiträge: 127
Registriert: 28.05.2003

erstellt am: 28. Jun. 2004 16:19    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Manuel Sauter 10 Unities + Antwort hilfreich

Tom hat völlig recht, das muss so sein. Ist allerdings ein wenig unbefriedigend oder?

Ich mach' hier mal ein Beispiel, das sehr schön illustriert wo dir Krux dieser Verhaltensweise konkret liegt:

Code:

(fix(/ 5.6 0.7)) -> 8 wunderbar, alles klar

(fix(/ 5.6 0.8)) -> 6 oops ..


Wie bereits festgestellt, liegt das an der internen Iplementierung von Floatingpoint-Darstellungen die ist bekannter Weise recht ungenau, weil im Binär-System abgeschnitten wird, aber nicht Dezimal, wie wir das gewohnt sind. Zahlen, die sich wunderbar im Dezimal-System darstellen lassen (z.B. 0.8) kann ich als Binär-Bruch nur runden, wie es mit den Dezimal-Brüchen der Fall ist bei 1/7 (die Dezimal-Bruch-Darstellung hierfür sieht z.B. so aus: 0.142857 das ist aber mit Sichheit nicht 1/7). Da ist also nix zu machen ..

Blöde ist, dass das Beispiel oben ohne fix ganz vertrauenswürdig aussieht:

Code:

(/ 5.6 0.7) -> 8.0

(/ 5.6 0.8) -> 6.0


Das liegt daran, dass AutoCAD beim Darstellen der Zahlen auf seine Zeichenketten-Umwandlung zurück greift und die nicht nur abschneidet. Es wird uns also etwas anderes angezeigt, als ausgerechnet .. blöde.

Deshalb gibt's da einen üblen Hack, der aber das tut was wir (vielleicht) wollen - jedenfalls benutze ich ihn, wenn ich Ganzzahl-Rundungen brauche:

Code:

(defun :fix (#val)
  (setq #val (vl-princ-to-string #val))
  (if (distof #val)
    (atoi #val)
  )
)

Wer mag, soll hiermit glücklich werden.

Achim Dabrunz

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

mapcar
Mitglied
CADmin



Sehen Sie sich das Profil von mapcar an!   Senden Sie eine Private Message an mapcar  Schreiben Sie einen Gästebucheintrag für mapcar

Beiträge: 1250
Registriert: 20.05.2002

Time flies like an arrow, fruit flies like a banana (Groucho Marx)

erstellt am: 28. Jun. 2004 16:39    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Manuel Sauter 10 Unities + Antwort hilfreich

Achim, da ist ein kleiner Tippfehler drin, der verwirren könnte:

Code:

(/ 5.6 0.8) -> 7.0 ... erwartungsgemäß

(fix(/ 5.6 0.8)) -> 6.0 ... oops!


Und hier noch ein kleines Beispiel zum Nachdenken: A und B sind beide von 0 verschieden. A + B = C, aber A == C ?

Code:

(defun test( / a b c)
  (setq a 0.1234E+1)
  (setq b 5.6789E-20)
  (setq c(+ a b))
  (= c a)  ; => T
)

Gruß, Axel

------------------

Meine AutoLisp-Seiten
Meine private Homepage
Mein Angriff auf dein Zwerchfell
Mein Lexikon der Fotografie
Mein gereimtes Gesülze

[Diese Nachricht wurde von mapcar am 28. Jun. 2004 editiert.]

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Manuel Sauter
Mitglied



Sehen Sie sich das Profil von Manuel Sauter an!   Senden Sie eine Private Message an Manuel Sauter  Schreiben Sie einen Gästebucheintrag für Manuel Sauter

Beiträge: 28
Registriert: 29.10.2003

erstellt am: 28. Jun. 2004 16:43    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

OK, habe das Problem verstanden.
Danke an alle

Gruß Manuel

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP


Ex-Mitglied

erstellt am: 28. Jun. 2004 17:36    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat

Zitat:
Original erstellt von Dabrunz:
Deshalb gibt's da einen üblen Hack, der aber das tut was wir (vielleicht) wollen - jedenfalls benutze ich ihn, wenn ich Ganzzahl-Rundungen brauche:

Code:

(defun :fix (#val)
  (setq #val (vl-princ-to-string #val))
  (if (distof #val)
    (atoi #val)
  )
)



vl-princ-to-string ist oft nicht so hilfreich, weil hier die Genauigkeit an die Anzeigegenauigkeit gekoppelt ist und IIRC maximal 8 Dezimalstellen beträgt. RTOS hängt wiederum von Systemvariablen wie DIMZIN ab, die einfach durch einen Wechsel eines Bemaßungsstils verstellt werden. Blieb also nur die Programmierung einer eigenen AT-RTOS Funktion übrig:

(defun at-rtos (zahl modus genau / result olddimzin)
  (setq olddimzin (getvar "DIMZIN"))
  (setvar "DIMZIN" 8)
  (setq result (rtos zahl modus genau))
  (setvar "DIMZIN" olddimzin)
  (if (and (= 'INT (type (read result)))
  (/= 0 genau)
  )
    (setq result (strcat result ".0"))
  )
  result
)

Das nenne ich nun wirklich einen üblen Hack (man beachte die "Umrechnung" eines unerwünschten INT-Ergebnisses in einen String, der eine Fliesskommazahl enthält), aber mir ist bis heute noch nichts Besseres eingefallen, und ich verwende AT-RTOS ausnahmslos dort, wo andere Leute nur RTOS verwenden:

Befehl: (setq zahl 749.9999999999998)
750.0
Befehl: (= zahl 750.0)
nil
Befehl: (= (read (at-rtos zahl 2 10)) 750.0)
T

Gruß
Tom Berger

------------------



Ex-Mitglied

erstellt am: 28. Jun. 2004 17:54    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat

Zitat:
Original erstellt von mapcar:
Und hier noch ein kleines Beispiel zum Nachdenken: [...]

Da fällt mir noch eine Anekdote ein, die an dieser Stelle unbedingt erzählt werden muss - schliesslich hat die ESA über 5 Milliarden Euro dafür ausgegeben, dass Informatik-Studenten 1A-Anschauungsmaterial für das Thema "Fliesskommaüberlauf" erhalten :-)

Die allererste Ariadne 5 war eigentlich schon ein Meisterwerk, dumm nur, dass der Navigationscomputer versagt hat. Noch dümmer: der Navigationscomputer samt Software war identisch mit dem, der in der Ariadne 4 schon zigmal allerbestens funktioniert hat. Man hat dieses System ganz bewußt ohne jede Änderung aus der Ariadne 4 in die Ariadne 5 übernommen, weil man wusste: never change a runnig system.

Der Haken war halt, dass die Ariadne 5 ziemlich viel schwerer ist als die Ariadne 4, und dass ein schon immer in der Software vorhandener Bug sich bei der leichteren Rakete nicht auswirkte. Bei der Ariadne 5 aber gab's wegen des höheren Gewichts einen Fliesskommaüberlauf, der den Computer dazu brachte, die Rakete um 180 Grad herum zu steuern. Also nach unten statt nach oben :-)

Gruß
Tom Berger

------------------




Innenarchitekt Büro- und Objektplanung / New Work - Innenarchitekt / Interior Designer / Architekt für Einrichtungs- und Planungskonzepte bzw. CAD-Planer / pCon.planer (w/m/d)

New Work, agiles Arbeiten, - alle reden darüber, doch bei uns steckst Du mittendrin.

Wir sind ein familiäres, engagiertes Team mit kreativen und verantwortungsbewussten Köpfen, die ein gemeinsames Ziel vereint: Objekte zu planen und einzurichten, in denen man sich nicht nur gut fühlt, sondern in denen man Kraft und Inspiration für den Alltag tanken kann.

Fairness miteinander, Respekt und Ehrlichkeit sowie ein hohes Maß an Eigenverantwortung prägen unsere Arbeitsweise....

Anzeige ansehenArchitektur
CADmium
Moderator
Maschinenbaukonstrukteur




Sehen Sie sich das Profil von CADmium an!   Senden Sie eine Private Message an CADmium  Schreiben Sie einen Gästebucheintrag für CADmium

Beiträge: 13508
Registriert: 30.11.2003

.

erstellt am: 28. Jun. 2004 19:38    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Manuel Sauter 10 Unities + Antwort hilfreich

..und nochwas ohne Typumwandlung .. wenn auch ein wenig länger 

(defun ROUND (ZAHL STELLEN / TEMP )
  (if (and(numberp ZAHL) (=(type STELLEN) 'INT))
    (progn
      (setq TEMP (abs ZAHL))
      (repeat STELLEN (setq TEMP (* TEMP 10.0)))     
      (cond 
        ( (> (- TEMP (fix TEMP)) 0.5) (setq TEMP (+ (fix TEMP) 1)))
        ( (< (- TEMP (fix TEMP)) 0.5) (setq TEMP    (fix TEMP)  ))
        ( (= (- TEMP (fix TEMP)) 0.5)         
          (if (equal (/ (fix TEMP) 2.0) (fix(/ (fix TEMP) 2.0)) 0.001)
            (setq TEMP    (fix TEMP)  )
            (setq TEMP (+ (fix TEMP) 1))
          ) 
        )
      )
      (repeat STELLEN (setq TEMP (/ TEMP 10.0)))
      (setq TEMP (* TEMP (if (< Zahl 0 ) -1.0 1.0)))
    )
  )
  TEMP   
)

.. kann auch erweitert werden auf runden auf vielfaches von X usw. mal als Anstoß für eine algemeinere Funktion.

------------------
- Thomas -

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Anzeige.:

Anzeige: (Infos zum Werbeplatz >>)

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen

nächster neuerer Beitrag | nächster älterer Beitrag
Antwort erstellen


Diesen Beitrag mit Lesezeichen versehen ... | Nach anderen Beiträgen suchen | CAD.de-Newsletter

Administrative Optionen: Beitrag schliessen | Archivieren/Bewegen | Beitrag melden!

Fragen und Anregungen: Kritik-Forum | Neues aus der Community: Community-Forum

(c)2023 CAD.de | Impressum | Datenschutz