C++ zukunftssicher?
-
net schrieb:
Optimizer schrieb:
Beispiel 1: Prozessor A rechnet -1 / 10 == -1, Prozessor B rechnet -1 / 10 == 0
prozessor A ist eindeutig kaputt
Nein, der Rest ist 9. Nur weil du das nicht kennst, heißt das nicht, dass es das nicht gibt. So ein System hat Vorteile beim arithmetischen Shiften.
-
Optimizer schrieb:
net schrieb:
Optimizer schrieb:
Beispiel 1: Prozessor A rechnet -1 / 10 == -1, Prozessor B rechnet -1 / 10 == 0
prozessor A ist eindeutig kaputt
Nein, der Rest ist 9. Nur weil du das nicht kennst, heißt das nicht, dass es das nicht gibt. So ein System hat Vorteile beim arithmetischen Shiften.
das hat vorteile? welche? wo gibt es das? hast du ein beispiel?
-
Ich bin darüber gestolpert als ich mit dem MMIX-Assembler gearbeitet habe. Ich weiß jetzt aber nicht mehr, ob der Rest wirklich 9 war. Müsste ich drüber nachdenken, wie dieses System funktioniert.
Die Vorteile beim shiften aber liegen doch auf der Hand. Der arithmetische Rechtsshift von -1 ist billig:1111 / 2 = 1111
Einfach den Wert vom MSB nachschieben, bei positiven Zahlen ergibt sich das gewohnte Verhalten und bei negativen ist hier -1/2 == -1
-
huch? komisch. schlieslich ist eine division was anderes als ein bitshift (bis auf ein paar wenige ausnahmen). wie so'n prozessor intern seine bits verwaltet ist ja eigentlich egal, aber eine integerdivision muss doch 0 ergeben, wenn der teiler zu gross ist, oder nicht? davon abgesehn: wenn man sich fehler einhandelt beim shiften von negativen zahlen hat man natürlich selber schuld...
-
huch? komisch. schlieslich ist eine division was anderes als ein bitshift (bis auf ein paar wenige ausnahmen). wie so'n prozessor intern seine bits verwaltet ist ja eigentlich egal, aber eine integerdivision muss doch 0 ergeben, wenn der teiler zu gross ist, oder nicht?
Nein. Die Division ist dort so definiert, damit man einen arithmetischen Shift leichter bauen kann. Außerdem ist es mathematisch korrekter, weil der Rest immer positiv ist. Man muss das System nicht besser finden, aber es gibt es halt.
davon abgesehn: wenn man sich fehler einhandelt beim shiften von negativen zahlen hat man natürlich selber schuld...
Was soll denn das jetzt? Ich habe dir gezeigt, dass es Prozessoren gibt, die anders dividieren. Was hat das mit "selber schuld" zu tun?

-
also ich finde das seltsam. seit wann kann jeder selber definieren was bei einer division herauskommt?. na gut, dann bastel ich eben einen prozessor der bei division durch grosse zahlen 0x81 berechnet, weil's sich so schön digital verarbeiten lässt. ist ja albern sowas (daumen runter!)
btw: man kann nicht alle / durch bitshifts ersetzen. malnehmen aber geht.
-
Optimizer! Deine Ansicht ist wirklich merkwürdig und ich kann dir hier auch nicht zustimmen. Denn du argumentierst in etwa so: "Ein Ausnahme-Prozessor hebt die Gesetze der Mathematik auf, weil er keinen DIV-Befehl kennt." So, und das ist irgendwie nicht richtig.
Klar, eine ALU ist dafür da um schneller mal eine Division zu machen. Aber ich wende die ALU nur dann an, wenn es auch ins mathematisch passt. Wenn es nicht passt, muß ich ein Software-DIV benutzen. Wenn ein C++ Compiler das nicht macht, ist der Compiler für ernsthafte Anwendungen unbrauchbar.
Ich habe hier ein ARM-Buch (Advanced Risc Maschine Prozessor) von einem der ARM-Mitentwickler. Und dieser stellt auch ein Software-DIV vor, das den fehlenden DIV-Befehl im ARM kompensiert. Nicht aus Jux und Dollerei, sondern damit man vernünftig dividieren kann. Trotzdem kommt in dem Buch die ALU des ARM nicht zu kurz. Aber ich werde mich hüten das Software-DIV nicht zu benutzen. Vorallem, was macht man denn mit MS-Excel auf den ganzen PocketPCs oder die Palms, die ja einen ARM (StrongARM) drin haben? Rechnen die alle falsch, weil es kein DIV in Hardware gibt?
Überleg nochmal was du hier eigentlich versuchst durch zusetzen. Das kann nicht gut sein. Und ich hoffe, das kein enrnsthafter Compiler bei Divisionen ausschliesslich die ALU in Anspruch nimmt.
-
net schrieb:
also ich finde das seltsam. seit wann kann jeder selber definieren was bei einer division herauskommt?
Das ist nicht "falsch"! Wenn bei Modulo was negatives rauskommt, das ist eigentlich unmathematisch. Korrekt wäre:
- a % b € {0 ... b-1}
- a/b = c mit c*b + rest = asiehe http://de.wikipedia.org/wiki/Kongruenz_(Zahlentheorie)
Das ist halt dort so. Es hat mir selber nicht gefallen, es hat mich Zeit gekostet. Wir mögen beide das verbreitetere System lieber. Warum willst du jetzt mit mir über diesen Prozessor streiten?btw: man kann nicht alle / durch bitshifts ersetzen. malnehmen aber geht.
Wo habe ich das behauptet? Nirgendwo.
Artchi schrieb:
Optimizer! Deine Ansicht ist wirklich merkwürdig und ich kann dir hier auch nicht zustimmen. Denn du argumentierst in etwa so: "Ein Ausnahme-Prozessor hebt die Gesetze der Mathematik auf, weil er keinen DIV-Befehl kennt." So, und das ist irgendwie nicht richtig.
Ähm ne, sowas habe ich nicht gesagt. Ich habe gesagt, der Standard garantiert mir keine bestimmte Ganzzahlen-Arithmetik, das könnte problematisch sein, wenn man von "write once, run everywhere" ausgeht, was angeblich in C++ so toll ist.
Artchi schrieb:
Überleg nochmal was du hier eigentlich versuchst durch zusetzen.
Ich will was durchsetzen?

Artchi schrieb:
Das kann nicht gut sein. Und ich hoffe, das kein enrnsthafter Compiler bei Divisionen ausschliesslich die ALU in Anspruch nimmt.
Hoffe ich auch nicht. Aber die Garantie habe ich nicht. Hast du vergessen, worum es hier ging? Es ging um die Garantie, dass eine Division so abläuft, wie ich es erwarte und die gibt mir C++ nicht. Ich finde das schlecht, du sagst, die Compiler machen das schon "richtig". Ist aber nicht immer so, aber zumindest wäre es immer möglich. Solange das aber nicht spezifiziert ist, garantiert es dir der Standard zumindest nicht. Ganz einfach. Schau im Standard selber nach, wenn du es nicht glaubst.
So, jetzt bauen, wir mal den ganzen Stack wieder ab. Der Standard garantiert dies also nicht (hast du inzwischen nachgeschaut), also funktioniert "write once, run anywhere" nicht zwangsläufig. Du brauchst Compiler, die das nach deinen Wünschen richten, denn nicht jeder standardkonforme C++ Compiler muss es so machen, obwohl zwei Compiler völlig standardkonform sind, können sie unterschiedliche Programme erzeugen. Hui.
-
Optimizer schrieb:
Korrekt wäre:
- a % b € {0 ... b-1}
- a/b = c mit c*b + rest = adas ist ja auch okay so, aber wenn b vom betrag her grösser ist als a, dann ist c immer 0. der rest kann natürlich negativ sein, wenn a selber negativ ist. um auf dein beispiel mit dem komischen prozessor zurückzukommen: -1/10 ist 0 rest -1 und nicht -1 rest 0. das kann der doch nicht einfach vertauschen.
-
net schrieb:
Optimizer schrieb:
Korrekt wäre:
- a % b € {0 ... b-1}
- a/b = c mit c*b + rest = adas ist ja auch okay so, aber wenn b vom betrag her grösser ist als a, dann ist c immer 0. der rest kann natürlich negativ sein, wenn a selber negativ ist. um auf dein beispiel mit dem komischen prozessor zurückzukommen: -1/10 ist 0 rest -1 und nicht -1 rest 0. das kann der doch nicht einfach vertauschen.
Ne, einfach vertauschen tut er es auch nicht.
Es kommt -1 bei der Division raus und Rest 9. Einen Rest von -1 gibt es nicht, denn er liegt nicht in { 0 ... b-1 }.
-
das heisst: es fehlt uns noch eine dritte regel, um integer-division und modulo eindeutig zu machen. das ist ja grausam!
-
Optimizer schrieb:
Höh? Weil es nicht abgedeckt ist, ist es egal?
Exakt! Wenn ich auf einem System nicht so arbeiten kann, wie es der Standard vorschreibt, dann ist mir bewusst, dass ich nicht plattformunabhängig bin. In so einem Fall ist es mir persönlich egal, wenn ich Code habe, den ich auf anderen Systemen nicht einfach so wiederverwenden kann. Ich glaube aber auch nicht, dass ich mit irgendeiner Sprache Anwendungen schreiben kann, die wirklich auf _allen_ Systemen laufen.
Optimizer schrieb:
Ja sind sind eindeutig implementation-defined definiert.
Warum behauptest du, das sei irrelevant? Es ist äußerst unglaubwürdig, "write once, run anywhere" zu postulieren und dann zu behaupten dass Unterschiede in der Arithmetik irrelevant sind. Unterschiede in der Arithmetik verändern das Verhalten deines Programms und sind für die Semantik eines Programm höchst relevant. Du musst es umschreiben, damit es sich auf der neuen Plattform wie gewohnt verhält.Ersten, du denkst zu viel low-level. Wir reden hier immer noch über C++ und nicht über Assembler. Und zweitens, es gibt keine Unterschiede in der Arithmetik, höchstens Spezialfälle. Wie ich schon sagte, die Operatoren sind eindeutig definiert. Hier nur mal ein kleiner Auszug als Beispiel:
The binary * operator indicates multiplication.
Multiplikation bedeutet nunmal Multiplikation. Und ich verstehe das im mathematischen Sinne. Kann sein, dass du das anders verstehst. Ich kenne allerdings nichts anderes. Letztendlich bedeutet das, dass zB 5 multipliziert mit 3 immer 15 ergibt. Nicht 14 und auch nicht 16, sondern exakt 15. Wie letztendlich die Darstellung der Werte auf Bitebene aussieht oder wie die Prozessorbefehle für die Rechnung aussehen, sind mir doch vollkommen egal. Es mag ja sein, dass es CPUs gibt, die solch exotische Ergebnisse wie bei deinem Beispiel ausspucken. Dass es mathematisch trotzdem korrekt ist, darum hat sich der Compiler zu kümmern. Wie er das macht und welche Kombinationen von Befehlen er benutzt, ist seine Sache. Ich sag es nochmal, wir reden bei C++ immer noch von einer Hochsprache und nicht von irgendwelchen Assembler Exzessen. Und sollte ein Compiler das nicht packen, dann, wie Artchi schon sagte, ist er nicht brauchbar.
Optimizer schrieb:
Darauf wollte ich nicht hinaus. Die Header können unterschiedlich implementiert sein, z.B. könnte die Implementierung von <string> den Header <cstring> inkludieren, bei einem anderen Compiler aber nicht. In einem Programm, wo ich jetzt <string> inkludiere, steht mir dann strcpy() vielleicht zur Verfügung, vielleicht auch nicht.
Das ist doch vollkommen bedeutungslos. Du hast meinen Beitrag überhaupt nicht verstanden. Der Standard spezifiziert für alles Mögliche die zugehörige Headerdatei. Wenn du also strcpy() brauchst, dann hast du gefälligst <cstring> einzubinden. <string> interessiert hier keine Sau.