<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Unverständliches Rechenergebnis (Datentypen?)]]></title><description><![CDATA[<p>Hallo liebe C++-Gemeinde <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Ich habe ein weiteres Problem, das sich auf folgenden Code reduzieren lässt:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{
    unsigned long a(4);
    unsigned long b(10);
    double faktor(1.2);
    long ergebnis;

    ergebnis = (a - b) * faktor;

    cout &lt;&lt; &quot;Ergebnis: &quot; &lt;&lt; ergebnis &lt;&lt; endl;

    return 0;
}
</code></pre>
<p>Das Ergebnis ist nicht wie erwartet -7, sondern -2147483648.<br />
Ich bin mir ziemlich sicher, dass der Fehler in der Umrechnung der verschiedenen Datentypen liegt.<br />
Da (a - b) als Ergebnis einen unsigned long liefert, wird das Ergebnis falsch - komischerweise aber erst, wenn es mit einem Gleitkomma-Typ verrechnet wird - die direkte Umwandlung in ein signed long funktioniert hingegen.</p>
<p>Was kann ich denn dagegen tun? (a - b) explizit in einen signed long umwandeln?</p>
<p>Viele Grüße,<br />
lyrichter</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/276025/unverständliches-rechenergebnis-datentypen</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 14:13:17 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/276025.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 25 Oct 2010 15:32:09 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 16:20:27 GMT]]></title><description><![CDATA[<p>Hallo liebe C++-Gemeinde <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Ich habe ein weiteres Problem, das sich auf folgenden Code reduzieren lässt:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main()
{
    unsigned long a(4);
    unsigned long b(10);
    double faktor(1.2);
    long ergebnis;

    ergebnis = (a - b) * faktor;

    cout &lt;&lt; &quot;Ergebnis: &quot; &lt;&lt; ergebnis &lt;&lt; endl;

    return 0;
}
</code></pre>
<p>Das Ergebnis ist nicht wie erwartet -7, sondern -2147483648.<br />
Ich bin mir ziemlich sicher, dass der Fehler in der Umrechnung der verschiedenen Datentypen liegt.<br />
Da (a - b) als Ergebnis einen unsigned long liefert, wird das Ergebnis falsch - komischerweise aber erst, wenn es mit einem Gleitkomma-Typ verrechnet wird - die direkte Umwandlung in ein signed long funktioniert hingegen.</p>
<p>Was kann ich denn dagegen tun? (a - b) explizit in einen signed long umwandeln?</p>
<p>Viele Grüße,<br />
lyrichter</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1970461</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970461</guid><dc:creator><![CDATA[lyrichter]]></dc:creator><pubDate>Mon, 25 Oct 2010 16:20:27 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 15:57:11 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>das Problem liegt darin, dass deine Rechnung (a-b)= -6 ergibt, und das nicht im Wertebereich eines unsigned long liegt. Muss dein Long tatsächlich unsigned sein? Wie du schon selbst festgestellt hast, tritt der Fehler nicht bei signed long auf...</p>
<p>Noch eine Idee von mir: Wenn es sich um unsigned long drehen MUSS, UND du weißt, dass b größer als a ist, dann schreib deine Problem-Rechnung doch so:</p>
<pre><code class="language-cpp">ergebnis = - ((b - a) * faktor);
</code></pre>
<p>Kleiner Nachtrag: Versuch mal das folgende:</p>
<pre><code class="language-cpp">ergebnis = (static_cast&lt;long&gt;(a) - static_cast&lt;long&gt;(b)) * faktor
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1970474</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970474</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 25 Oct 2010 15:57:11 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 15:57:10 GMT]]></title><description><![CDATA[<p>Hey,</p>
<p>ist dir denn überhaupt klar, wozu das Keyword <code>unsigned</code> überhaupt gut ist?</p>
<p>Du sagst ja damit, dass die Zahlen a und b vorzeichenlos sind und somit nur positive Werte erhalten können. Das Ergebnis dieses <strong>Ausdrucks</strong> ist somit klar definiert.</p>
<p>unsigned &lt;operator&gt; unsigned = unsigned</p>
<p>Nun kommt bei deiner Berechnung aber ein negativer Wert heraus, welcher nicht dem erwarteten Datentyp von unsigned entspricht und auch nicht in diesen konvertiert werden kann. Das Verhalten ist an dieser Stelle undefiniert.</p>
<p>Du könntest das so lösen:</p>
<pre><code class="language-cpp">ergebnis = (static_cast&lt;long&gt;(a) - static_cast&lt;long&gt;(b)) * faktor;
</code></pre>
<p>Damit hast du als Ergebnis aber noch immer nicht das korrekte Ergebnis. Schließlich ist ergebnis ein long. Und ein long ist ein ganzzahliger Datentyp, und kann somit keine Nachkommastellen speichern.</p>
<p>So würde es also gehen:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main()
{
	unsigned long a(4);
    unsigned long b(10);
    double faktor(1.2);
    double ergebnis;

    ergebnis = (static_cast&lt;long&gt;(a) - static_cast&lt;long&gt;(b)) * faktor;

    cout &lt;&lt; &quot;Ergebnis: &quot; &lt;&lt; ergebnis &lt;&lt; endl;

    return 0;
}
</code></pre>
<p>Um die Berechnung nochmal zu erläutern. Zunächst wird natürlich die Klammer ausgewertet. Dabei handelt es sich um ein <code>unsigned long</code> , welcher in ein <code>signed long</code> konvertiert wird und anschließend von einem <code>unsigned long</code> , der aber auch in ein <code>signed long</code> konvertiert wird subtrahiert wird.</p>
<p>Da also nun beide Variablen vom Typ <code>signed long</code> sind, ist auch das Ergebnis dieses Ausdrucks <code>signed long</code> .</p>
<p>Anschließend wird das Ergebnis vom Typ <code>signed long</code> mit einem <code>double</code> multipliziert. Das Ergebnis dieses Ausdrucks ist somit auch ein <code>double</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1970475</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970475</guid><dc:creator><![CDATA[,,,,,]]></dc:creator><pubDate>Mon, 25 Oct 2010 15:57:10 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 16:51:42 GMT]]></title><description><![CDATA[<p>Erst einmal vielen Dank für die Antworten!</p>
<p>Nun habe ich eingie Rückfragen/Anmerkungen:</p>
<blockquote>
<p>ist dir denn überhaupt klar, wozu das Keyword unsigned überhaupt gut ist?</p>
</blockquote>
<p>Ja.</p>
<blockquote>
<p>Wenn es sich um unsigned long drehen MUSS, UND du weißt, dass b größer als a ist</p>
</blockquote>
<p>Ja, es muss laut Aufgabenstellung, aber ich weiß im Voraus leider nicht, ob a oder b größer ist.</p>
<blockquote>
<p>Wie du schon selbst festgestellt hast, tritt der Fehler nicht bei signed long auf...</p>
</blockquote>
<p>Das habe ich zwar auch festgestellt, war aber nicht das, was ich in meinem Eingangspost meinte. Ich wundere mich nur darüber, dass folgender Code funktioniert, da (a - b) ja vom Typ unsigned long sein sollte.</p>
<pre><code class="language-cpp">unsigned long a(4);
    unsigned long b(10);
    long ergebnis;

    ergebnis = (a - b);
</code></pre>
<p>Die Umwandlung von unsigned long nach long wird hier dann wohl automatisch vorgenommen und funktioniert hier. Sogar so gut, dass aus einem Wert ohne Vorzeichen der korrekte Wert mit Vorzeichen wird, was mich wie gesagt sehr wundert.</p>
<p>Außerdem funktioniert auch</p>
<pre><code class="language-cpp">unsigned long a(4);
    long b(-10);
    long ergebnis;

    ergebnis = a + b;
</code></pre>
<p>Das kann ich mir ebenfalls nicht erklären, da<br />
long + unsigned long --&gt; unsigned long<br />
und ein unsigned long dann wieder in ein korrektes signed long mit Vorzeichen umgewandelt wird.</p>
<blockquote>
<p>Damit hast du als Ergebnis aber noch immer nicht das korrekte Ergebnis. Schließlich ist ergebnis ein long. Und ein long ist ein ganzzahliger Datentyp, und kann somit keine Nachkommastellen speichern.</p>
</blockquote>
<p>Mein Fehler: Es sollte nicht, wie ich erst fälschlcherweise geschrieben habe, 7.2 in ergebnis gespeichert werden, sondern natürlich 7. Das Abschneiden der Nachkommastellen durch die Umwandlung ist ok und eingeplant.</p>
<p>Ich merke aber schon, dass das alles (wieder mal) etwas aus dem Ruder läuft. Anstatt mein problem total zu isolieren, hier mehr oder minder das Original-Problem:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
#define PI 3.14159265

using namespace std;

main()
{
        unsigned long x(2), y(15);
        unsigned long zx(1), zy(19);
        double winkel(30);
        double rad;
        long new_x, new_y;

	rad = winkel * PI/180;
	new_x = (x - zx) * cos(rad) - (y - zy) * sin(rad) + zx;
	new_y = (y - zy) * cos(rad) + (x - zx) * sin(rad) + zy;

	cout &lt;&lt; new_x &lt;&lt; endl;
	cout &lt;&lt; new_y &lt;&lt; endl;
}
</code></pre>
<p>Im Moment kommt da noch völliger Unsinn heraus. Die korrekte Größenordnung dürfte new_x = 4, new_y = 16 sein.<br />
Wie gehe ich jetzt am besten vor? Ist es sinnvoll, einfach wie oben von ,,,,, beschrieben vorzugehen, nur jetzt bei den beiden summanden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1970493</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970493</guid><dc:creator><![CDATA[lyrichter]]></dc:creator><pubDate>Mon, 25 Oct 2010 16:51:42 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 16:53:23 GMT]]></title><description><![CDATA[<p>du musst nicht vorher wissen we4r größer ist ... das kann man testen und die dementsprechende Methode wählen ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1970495</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970495</guid><dc:creator><![CDATA[padreigh]]></dc:creator><pubDate>Mon, 25 Oct 2010 16:53:23 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 17:05:03 GMT]]></title><description><![CDATA[<p>Vorsicht. Dass die Umwandlung so funktioniert, wie du es erwartest, ist im C++-Standard nicht garantiert. Auf PCs funktioniert es deshalb, weil dort Integer in Zweierkomplementdarstellung gespeichert werden, d.h. beispielsweise bei 8-Bit-Integern:</p>
<pre><code>0111 1111 =  127
1000 0000 = -128 (bzw. 128, wenn vorzeichenlos interpretiert)
1111 1111 = -1   (bzw. 255, wenn vorzeichenlos interpretiert)
</code></pre>
<p>Die Umwandlung zwischen vorzeichenbehaftet und vorzeichenlos ist dann rein konzeptionell, und der Wertebereich wickelt sich sowohl bei vorzeichenlosen als auch bei vorzeichenbehafteten Integern herum. Jetzt ist das zwar auf heutigen Architekturen allgemein üblich, es hat aber durchaus auch schon mal andere Darstellungsarten gegeben.</p>
<p>Vom Standard garantiert ist: Vorzeichenlose Integer rechnen modulo 2^Breite. Das Verhalten der Zuweisung in einen vorzeichenbehafteten Integer außerhalb seines Wertebereichs ist dagegen nicht definiert.</p>
<p>Um also auf der sicheren Seite zu sein, musst du die Operanden der Differenz in vorzeichenbehaftete longs casten (und sicherstellen, dass ihre Werte davon dargestellt werden können).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1970498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970498</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 25 Oct 2010 17:05:03 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 17:54:33 GMT]]></title><description><![CDATA[<p>padreigh schrieb:</p>
<blockquote>
<p>du musst nicht vorher wissen we4r größer ist ... das kann man testen und die dementsprechende Methode wählen ...</p>
</blockquote>
<p>Ja, aber das finde ich etwas umständlich mit einem langen Ausdruck wie diesem.<br />
Gibt es keine andere Möglichkeit mit einigen geschickten Typumwandlungen?</p>
<p>Oder ist das tatsächlich die beste Lösung?</p>
<p>Edit:<br />
@seldon: Huch, deinen Beitrag hatte ich völlig übersehen.</p>
<p>seldon schrieb:</p>
<blockquote>
<p>Um also auf der sicheren Seite zu sein, musst du die Operanden der Differenz in vorzeichenbehaftete longs casten</p>
</blockquote>
<pre><code class="language-cpp">ergebnis = (static_cast&lt;long&gt;(a) - static_cast&lt;long&gt;(b)) * faktor;
</code></pre>
<p>Du meinst so? Und (long * double) umgewandelt in long ist sicher?</p>
<p>seldon schrieb:</p>
<blockquote>
<p>(und sicherstellen, dass ihre Werte davon dargestellt werden können).</p>
</blockquote>
<p>Du meinst, sicherstellen, dass die Operanden nicht zu groß sind? Wie kann ich das tun?</p>
<p>Viele Grüße,<br />
lyrichter <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1970499</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970499</guid><dc:creator><![CDATA[lyrichter]]></dc:creator><pubDate>Mon, 25 Oct 2010 17:54:33 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 19:09:15 GMT]]></title><description><![CDATA[<p>So, das Programm funktioniert jetzt, nur leider ohne Schutz vor Überlaufen bei der Konvertierung von unsigned long nach signed long.</p>
<p>Eine andere Frage ist dabei aber aufgetaucht: Sind die beiden nachfolgenden Codes äquivalent?</p>
<pre><code class="language-cpp">unsigned long bla(5);
long blub(bla);
</code></pre>
<pre><code class="language-cpp">unsigned long bla(5);
long blub;

blub = static_cast&lt;long&gt;(bla);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1970587</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970587</guid><dc:creator><![CDATA[lyrichter]]></dc:creator><pubDate>Mon, 25 Oct 2010 19:09:15 GMT</pubDate></item><item><title><![CDATA[Reply to Unverständliches Rechenergebnis (Datentypen?) on Mon, 25 Oct 2010 19:17:09 GMT]]></title><description><![CDATA[<p>Beides gleich beschissen...</p>
<p>Schreib einfach</p>
<pre><code class="language-cpp">ergebnis = (a&gt;b?a-b:b-a) * faktor * (a&gt;b?1:-1);
</code></pre>
<p>dann hast du das Problem gar nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1970592</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1970592</guid><dc:creator><![CDATA[mathematiker]]></dc:creator><pubDate>Mon, 25 Oct 2010 19:17:09 GMT</pubDate></item></channel></rss>