die achte Mersenne-Primzahl 2147483647

Fehler in Firmware und WebUI & Workarounds

Moderator: Co-Administratoren

Antworten
alchy
Beiträge: 7164
Registriert: 24.02.2011, 02:34

die achte Mersenne-Primzahl 2147483647

Beitrag von alchy » 28.05.2018, 21:22

von hier
viewtopic.php?f=65&t=43679&view=unread#p437432

Code: Alles auswählen

CCU2
VERSION=2.31.25

Version: 2.1.369
Build: R1.00.0388.0127



versucht man eine Zahl größer als 2147483647.000000 in Integer zu wandeln, bleibt es bei der o.g. Primzahl

Während also

Code: Alles auswählen

real devVal= 2147483647.000000 ;
integer itemp = devVal.ToInteger();
WriteLine("aus dem Wert: " #devVal #" wird integer = " #itemp);  
noch

Code: Alles auswählen

aus dem Wert: 2147483647.000000 wird integer = 2147483647 
ergibt, bleibt es ab

Code: Alles auswählen

real devVal= 2147483648.000000 ;
integer itemp = devVal.ToInteger();

WriteLine("aus dem Wert: " #devVal #" wird integer = " #itemp);  
bei

Code: Alles auswählen

aus dem Wert: 2147483648.000000 wird integer = 2147483647
Alchy

.................... Full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

Familienvater
Beiträge: 6276
Registriert: 31.12.2006, 16:18
Wohnort: Rhein-Main

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von Familienvater » 28.05.2018, 21:52

Hi,

was ist Deiner Meinung nach Richtig? Es gibt keine Exceptions im eigentlichen Sinn in HM-Script, soweit ich weiß.
Ein "gescheite" Programmiersprache würde je nach Implementation im Idealfall einen Überlauf melden, wir haben hier wohl eine nicht ideale Implementation, mangels Interesse an der Rega und Co, was behauptet den die Legacy Rega zu der Geschichte?
Die Darstellungsmöglichkeiten in Integer sind da begrenzt, wir hätten vielleicht -1 als genau so falsche Lösung?

Der Familienvater

Benutzeravatar
jmaus
Beiträge: 2868
Registriert: 17.02.2015, 15:45
Wohnort: Dresden
Kontaktdaten:

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von jmaus » 28.05.2018, 22:43

Hier muss ich Familienvater recht geben.

"integer" ist eben maximal 32bit breit und das bedeutet, dass der erlaubte Wertebereich von -2147483647 bis +2147483647 geht. Das steht übrigens so auch in der Skriptdokumentation (siehe https://www.eq-3.com/Downloads/eq3/down ... g_V2.2.pdf) auf Seite 6. Wenn man also eine Floating Point Zahl (real) hat die größer/kleiner als der Wertebereich ist kann zwangsläufig nicht das "richtige" rauskommen wenn man diese mittels ToInteger() in ein integer konvertiert.
RaspberryMatic 2.35.16.20180715 @ TinkerS mit ~150 HomeMatic Geräten + ioBroker – GitHubPayPal

Familienvater
Beiträge: 6276
Registriert: 31.12.2006, 16:18
Wohnort: Rhein-Main

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von Familienvater » 28.05.2018, 22:44

Nach dem ich noch kurz drüber nachgedacht habe, noch mein letztes Statement:

Es betreibt hoffentlich keiner die besagte Raketentechnik mit HM-Script, und dann wäre Int eh der falsche Datentyp.

Wann kann es zu solch einem (nicht erkannten) Überlauf kommen?
Wenn große Zahlen mit noch viel größeren Zahlen multipliziert, addiert oder sonstwie verrechnet werden, gerade beim Multiplizieren würde ich auf falsche "Gewichte" tippen.
Wenn man verschiedene Optionen hat, und will die bessere von verschiedenen Optionen "künstlich" ermitteln, vergibt man Gewichte, und sagt für sich persönlich z.B. mit ist es lieber, wenn es im Wohnzimmer wärmer ist, im Vergleich zu höheren Heizkosten.
Jeder kennt das, wenn er sich zwischen verschiedenen, gleichartigen? Dingen entscheiden muss, will ich lieber Cabrio, oder Kombi, oder ein kurzes Auto um überall parken zu können, oder einen LKW, weil der auch mal die SupersonderAngebotspalette Transportieren kann....
Der eine sagt sich, Nutzbarkeit als Cabrio hat Faktor 1000, Nutzbarkeit als Kombi hat Faktor 10, als LKW nur 1, und das Parken ist mir Faktor 100 wert, dann "gewinnt" etwas, was Cabrioähnlich ist. Ist jemand sehr auf Umzüge und Sonderangebote fokusiert, der Gewichtet den Ladefaktor des LKW mit 10000, den des Kombi mit 1000, und weil der auf dem Land wohnt, und es keine Parkplatzprobleme gibt, da ist der Faktor nur 1, und auch die landwirtschaftlichen Gerüche sind beim Cabrio aufdringlich, also Negativer Faktor 100. Hat einer viel zu viele Faktoren, die er bewerten will, dann, und nur dann sehe ich ein Problem, das man einen Integer zum Überlaufen bringt (mal Sekunden nach Christi Geburt außen vor), und dann frage ich mich, ob es noch einen Unterschied macht, ob nun das Integer-Cabrio oder der Integer-LKW gewinnt, der Programmierer hat eh vorher den falschen Datentyp gewählt, weil mit Faktoren von 0,1 oder 0,003333 hätte der Int eh nicht funktioniert, und dann wäre der real nicht übergelaufen...

Habe fertig,
der Familienvater

alchy
Beiträge: 7164
Registriert: 24.02.2011, 02:34

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von alchy » 29.05.2018, 16:28

Familienvater hat geschrieben: was ist Deiner Meinung nach Richtig?
Was richtig ist, darüber kann man gerne diskutieren.
Für mich ist es jedenfalls absolut nicht richtig, bei falscher Verwendung einfach die Obergrenze des möglichen Zahlenbereiches auszugeben und so tun als ob nix wäre. :!:
Familienvater hat geschrieben:was behauptet den die Legacy Rega zu der Geschichte?
Hättest du statt "nochmal kurz drüber nachzudenken" mal selber nachgeschaut, wüsstest du die Antwort. Sie macht ebenso.

jmaus hat geschrieben: Das steht übrigens so auch in der Skriptdokumentation
Willst du mir damit irgendetwas sagen? Kein Wort dagegen. Das steht da.

Nur
jmaus hat geschrieben:Wenn man also eine Floating Point Zahl (real) hat die größer/kleiner als der Wertebereich ist kann zwangsläufig nicht das "richtige" rauskommen wenn man diese mittels ToInteger() in ein integer konvertiert.
Die von dir angeführte Doku sollten sich die Programmierer bei EQ3 wohl mal bei Gelegenheit reinziehen. :wink:
Und das ^^ gehört eben zur Bugmeldung dazu. Ich habe das Script nur eingekürzt um es auf den Nenner zu bringen und "nachvollziehbare" Beispiele zu bringen.
Wie man in dem >> verlinktem Thread <<ja lesen kann sind es ja wohl ihre Konstrukte in den internen Scripten, welche zum Auffinden des Bugs führten.

Du kannst mir natürlich auch gerne erklären, wie man auf ein solches "Konstrukt" :

Code: Alles auswählen

integer ioldDevVal = (tmpOldDevVal.ToString().ToFloat() * 100000).ToInteger();
in den internen Scripten überhaupt kommt? (wobei es sich bei tmpOldDevVal um eine real handelt.

Familienvater hat geschrieben:Wann kann es zu solch einem (nicht erkannten) Überlauf kommen?.....
Jeder der eine Homematic und die entsprechenden Aktoren mit den originalen internen Scripten sein Eigen nennt, läuft Gefahr in diese Falle zu rennen.
Ich weiß nicht, was dein Post mit dem Problem an sich zu tun hat. Nicht verstanden um was es sich hier handelt?
Einfach mal Posten um des Postens willen? Partei ergreifen, Schutzfunktion?
Keine Ahnung was das soll, aber hilfreich ist es *IMHO* wohl wenig.


Meine Meinung:
  • EQ3 sollte die internen Scripte mal überprüfen. (da gibt es ja eh noch eine andere Bugmeldung, die auch ignoriert wird.)
  • .ToInteger() sollte nicht einfach die Obergrenze ausgeben, wenn der Zahlenbereich überschritten wurde.
Aber da es für Euch beide augenscheinlich nicht relevant ist, will auch nichts gesagt haben.

Der geneigte oder ungeneigte User soll sich selber ein Bild machen.


Alchy

.................... Full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

Benutzeravatar
jmaus
Beiträge: 2868
Registriert: 17.02.2015, 15:45
Wohnort: Dresden
Kontaktdaten:

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von jmaus » 29.05.2018, 17:00

Lieber Alchy,

kann das sein das du schon etwas sehr sperrig bist in letzter Zeit? Und Einsicht ist auch nicht gerade deine Stärke, oder? Aber lassen wir das...
alchy hat geschrieben: Was richtig ist, darüber kann man gerne diskutieren.
Für mich ist es jedenfalls absolut nicht richtig, bei falscher Verwendung einfach die Obergrenze des möglichen Zahlenbereiches auszugeben und so tun als ob nix wäre. :!:
Na dann lass uns mal starten zu diskutieren und erkläre uns mal bitte was du dir genau vorstellst wie denn ToInteger() darauf reagieren sollte? "-1" annehmen oder "0"? Hmm. alles irgendwie genauso falsch, oder? Es ist es so wie Familienvater gesagt hat, die ReGaHss hat keine Möglichkeit einen overflow oder underflow dem Nutzer bei solchen Operationen mitzuteilen genauso wenig wie bei einem

Code: Alles auswählen

integer i = 2147483647;
integer j = i + 100;
Auch das wird zwangsläufig dazu führen müssen das j einen "undefinierten" Wert annimmt. Man muss eben wissen was man tut und was der Wertebereich der Datentypen ist die man einsetzt. Aber vielleicht hast du ja eine Idee wie man das ganze doch irgendwie lösen könnte. Dann würde ich mich freuen das zu hören und könnte das dann auch entsprechend in die ReGa mit aufnehmen.
alchy hat geschrieben: Nur
jmaus hat geschrieben:Wenn man also eine Floating Point Zahl (real) hat die größer/kleiner als der Wertebereich ist kann zwangsläufig nicht das "richtige" rauskommen wenn man diese mittels ToInteger() in ein integer konvertiert.
Die von dir angeführte Doku sollten sich die Programmierer bei EQ3 wohl mal bei Gelegenheit reinziehen. :wink:
Und das ^^ gehört eben zur Bugmeldung dazu. Ich habe das Script nur eingekürzt um es auf den Nenner zu bringen und "nachvollziehbare" Beispiele zu bringen.
Wie man in dem >> verlinktem Thread <<ja lesen kann sind es ja wohl ihre Konstrukte in den internen Scripten, welche zum Auffinden des Bugs führten.
Wie gesagt, im Grunde ist das kein Bug das die ToInteger() Konvertierung bei einem solch großen Wert nicht das eigentlich erwartete Ergebnis bringt. Ein integer kann nunmal keine größere Zahl beherbergen. Was jedoch den internen Skript angeht in dem solch ein Konstrukt zu finden ist, nun dann wäre der "Bug" in dem internen Skript wohl eher das hier eben die Annahme des Entwicklers wohl gewesen ist das der entsprechende Float wert nie so groß wird das die Integerwandlung Gefahr läuft überzulaufen. Ob das immer noch der Fall ist, nun das müsste man sich anschauen und dann eben ggf. beheben. Allerdings zielt dein Beitrag hier in keinster Weise darauf ab den Finger auf das interne Skript zu lenken, sondern soweit ich ihn verstanden habe bist du ursprünglich davon ausgegangen das wohl im ToInteger() ein Bug sein müsste da es keine Zahl >2147483647 ausgeben kann. Und hier bist du eben dem benannten Wertebereich auf den Leim gegangen.

Natürlich könnte ich jetzt drüber nachdenken dem integer Typ ein paar bits mehr zu spendieren (z.B. 64bit draus zu machen). Aber ob das sinnvoll ist oder zu unerwünschten Nebeneffekten führt kann ich momentan schwer abschätzen.
alchy hat geschrieben: Du kannst mir natürlich auch gerne erklären, wie man auf ein solches "Konstrukt" :

Code: Alles auswählen

integer ioldDevVal = (tmpOldDevVal.ToString().ToFloat() * 100000).ToInteger();
in den internen Scripten überhaupt kommt? (wobei es sich bei tmpOldDevVal um eine real handelt.
Das ist eine Gute Frage die sich ohne den ursprünglichen Entwickler schwer lösen lässt. Ich kann hier nur vermuten das durch das ToString() eine art Rundung vorgenommen werden sollte bevor der Wert dann mit 100000 multipliziert wird um dann wiederum danach mittels ToInteger() die Nachkommestellen abzuschneiden. Das man das auch hätte anders/besser machen können, steht natürlich ausser Frage. Aber nun den Fehler in ToInteger() zu suchen ist eben aber leider genauso falsch.
alchy hat geschrieben:
Familienvater hat geschrieben:Wann kann es zu solch einem (nicht erkannten) Überlauf kommen?.....
Jeder der eine Homematic und die entsprechenden Aktoren mit den originalen internen Scripten sein Eigen nennt, läuft Gefahr in diese Falle zu rennen.
Ich weiß nicht, was dein Post mit dem Problem an sich zu tun hat. Nicht verstanden um was es sich hier handelt?
Einfach mal Posten um des Postens willen? Partei ergreifen, Schutzfunktion?
Keine Ahnung was das soll, aber hilfreich ist es *IMHO* wohl wenig.
Ich denke Familienvater hat hier (genauso wie ich) sehr genau verstanden um was es geht. Du hast dich jedoch im Umkehrschluss leider sehr ungünstig ausgedrückt denn dein Anfangsbeitrag zielt eben leider nicht darauf ab das entsprechende Konstrukt in dem internen Skript zu verdammen, sondern so wie Familienvater und ich ihn gelesen habe zielte er mehr darauf ab eben einen Fehler in ToInteger() selbst aufzudecken, den es aber eben aus genannten Gründen so nicht gibt.
alchy hat geschrieben: Meine Meinung:
  • EQ3 sollte die internen Scripte mal überprüfen. (da gibt es ja eh noch eine andere Bugmeldung, die auch ignoriert wird.)
  • .ToInteger() sollte nicht einfach die Obergrenze ausgeben, wenn der Zahlenbereich überschritten wurde.
Beim ersten Punkt geben ich dir vollkommen recht. Gerne kannst du aber selbst hier ein besseres Konstrukt vorschlagen um die besagte Aufgabe (Wandlung eines Real in ein Integer mit Rundung und abschneiden der Nachkommastellen) anders hinzubekommen als der ursprüngliche Entwickler es getan hat.

Beim zweiten Punkt solltest du IMHO noch einmal etwas mehr überlegen, denn mir fällt aktuell keine mögliche Lösung hierfür ein die nicht eine komplette Umstellung vieler Interna in der ReGa mit sich bringen würde um einen entsprechenden overflow/underflow dem Nutzer mitteilen zu können. Wie schon erwähnt, hier ist nicht nur ToInteger() betroffen sondern jede Art von integer Berechnungen in einem ReGa Skript die nahe der Wertebereichsgrenzen operieren. Aber vielleicht hast du ja eine elegante Lösung im Kopf, dann würde ich mich freuen diese zu hören...
RaspberryMatic 2.35.16.20180715 @ TinkerS mit ~150 HomeMatic Geräten + ioBroker – GitHubPayPal

deimos
Beiträge: 1338
Registriert: 20.06.2017, 10:38
Wohnort: Leimersheim
Kontaktdaten:

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von deimos » 29.05.2018, 17:59

Hi,

eine Idee für eine Lösung des Overflows in ToInteger() und ähnlichen Dingen wäre eine globale Bool Property, welche auf true gesetzt wird, falls es zum Überlauf kam (Also ähnliche Idee wie mit einem Carry Register in einer ALU).

Das wäre Non-breaking, vermutlich trivial zu implementieren und würde einen Workaround bieten.

Langfristig sollte man aber lieber überlegen auf eine andere Logikschicht zu kommen, RegaHss ist einfach nicht mehr zeitgemäß.

Viele Grüße
Alex

alchy
Beiträge: 7164
Registriert: 24.02.2011, 02:34

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von alchy » 29.05.2018, 20:10

jmaus hat geschrieben:kann das sein das du schon etwas sehr sperrig bist in letzter Zeit? Und Einsicht ist auch nicht gerade deine Stärke, oder? Aber lassen wir das..
Unterlass bitte gleich solche Sätze. Sowas zu schreiben und mit "Aber lassen wir das.. " zu beenden ist doch deiner immer noch nicht würdig.
jmaus hat geschrieben:Hmm. alles irgendwie genauso falsch, oder? Es ist es so wie Familienvater gesagt hat, die ReGaHss hat keine Möglichkeit einen overflow oder underflow
Natürlich wäre 0 oder -1 genau so falsch wie eben 2147483647. Will mich denn keiner verstehen?
Wenn es keine Möglichkeit gibt, ein Overflow in .ToInteger() abzufangen, dann ist dies schlecht, das war mir aber auch nicht bewußt.
Ein Scripterror wäre *IMHO* das Mindeste.

Code: Alles auswählen

integer i = 2147483647;
integer j = i + 100;
ergibt -2147483549

Und du ahnst es schon, auch das ist in meinen Augen ein Fehler.
jmaus hat geschrieben:Und hier bist du eben dem benannten Wertebereich auf den Leim gegangen
Achiwo, denn ich wurde schon vorher durch einen mitlesenden Freund gewarnt. Wahrscheinlich weil er ahnte, das es so enden würde.

jmaus hat geschrieben:nun dann wäre der "Bug" in dem internen Skript wohl eher das hier eben die Annahme des Entwicklers wohl gewesen ist das der entsprechende Float wert nie so groß wird das die Integerwandlung Gefahr läuft überzulaufen.
Genau so wird es sein. Also ist der Thread hier gelöst, der User in dem Thread ist ein Einzelschicksal und meine Bugmeldung falsch. Da ich das Gerät nicht besitze wird das eh schwer für mich.
jmaus hat geschrieben:Du hast dich jedoch im Umkehrschluss leider sehr ungünstig ausgedrückt denn dein Anfangsbeitrag zielt eben leider nicht darauf ab das entsprechende Konstrukt in dem internen Skript zu verdammen, sondern so wie Familienvater und ich ihn gelesen habe zielte er mehr darauf ab eben einen Fehler in ToInteger() selbst aufzudecken, den es aber eben aus genannten Gründen so nicht gibt.
Ungünstig ausgedrückt? Jo, das ist so sicherlich der Fall, das will ich gerne einsehen.
Schon im 2. Post hier im Thread sollte es aber eigentlich geklärt sein.
Ja es ist *IMHO* ein Fehler wenn .ToInteger() einfach irgendeine Zahl ausgibt statt einem Fehler.
Wenn das in Euren Augen kein Fehler ist, dann ist das auch gut. Hab ich alles schon oben geschrieben.
jmaus hat geschrieben:Gerne kannst du aber selbst hier ein besseres Konstrukt vorschlagen um die besagte Aufgabe (Wandlung eines Real in ein Integer mit Rundung und abschneiden der Nachkommastellen) anders hinzubekommen als der ursprüngliche Entwickler es getan hat.
Aber nicht doch.
Klar werde ich mir die Scripte bei Gelegenheit genauer anschauen.
Aber ich habe dem meldenden User vertraut, das seine Angaben einfach mal stimmen und seine Zählerstände dadurch verkehrt berechnet werden ohne das er irgendetwas selbst verschuldet hätte.

deimos hat geschrieben: eine Idee für eine Lösung des Overflows in ToInteger() und ähnlichen Dingen wäre eine globale Bool Property, welche auf true gesetzt wird, falls es zum Überlauf kam (Also ähnliche Idee wie mit einem Carry Register in einer ALU).
vielen Dank.

Alchy

.................... Full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

Benutzeravatar
Black
Beiträge: 711
Registriert: 12.09.2015, 22:31
Wohnort: Wegberg
Kontaktdaten:

Re: die achte Mersenne-Primzahl 2147483647

Beitrag von Black » 29.05.2018, 21:04

an der Typgrösse würde ich nicht schrauben... viel programmiersprachen definieren Maxint als 2147483647.
auch unter 64Bit Windows ergibt in python

Code: Alles auswählen

>>> import sys
>>> type(sys.maxsize)
<class 'int'>
>>> sys.maxsize
2147483647
Für solche Fälle wäre es vllt nicht ungeschickt, unter der Domäne System ein oder Mehrere Register einzuführen ,ähnlich dem was Daimos schon vorgeschlagen hat und was auf µC ebene das Statusregister ist, Auch auf SPS Ebene gibts ein derartikel register (Statusword), Carry bei Überlauf, Borrow bei Unterlauf, Div by Zero (Division durch Null, Wurzel Negativer Zahlen) als erste 3 Werte

Dann obliegt es dem Programmierer, nach der Wandlung das/die Flags auszuwerten und entsprechende Massnahmen durchzuführen.

Alternativ wäre ich auch einen neuen Datentyp LongInt nicht abgeneigt 2^63 -1 damit sollten die im Alltag einer Hausautomation vorkommenden zahlenbereiche eigentlich abgedeckt sein
Die Wahrheit ist ein Chor aus Wind
Meine Seite, ok noch bisschen im Aufbau

RaspberryMatic 2.31.25.20180225 mit Groundplane Antennenmod (Mein Grundstück ist halt etwas gross)
jede Menge Sensoren und Aktoren, Logamatic 2107 Gateway zum Buderus Kessel
ioBroker als Hauptsteuersystem und Visualisierung
Script Time Scheduler V1.2
Script Developer V2.27.1

Antworten

Zurück zu „HomeMatic - bekannte Bugs“