<?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[[Gelöst] Overflow Test - Integers]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>angenommen ich möchte überprüfen, ob das Addieren von zwei Integern a und b einen overflow erzeugen wird, welche (der beiden) Methode(n) ist besser/sind am besten?</p>
<pre><code>const int maxint = std::numeric_limits&lt;int&gt;::max();
const int minint = std::numeric_limits&lt;int&gt;::min();

bool add_is_safe(int lhs, int rhs)
{
    if (lhs &gt; 0 &amp;&amp; rhs &gt; 0)
        return (lhs &lt;= maxint - rhs);
    else if (lhs &lt; 0 &amp;&amp; rhs &lt; 0)
        return (lhs &gt;= minint + rhs);
    else
        return true;
}
// oder (von StackOverflow)
// ACHTUNG: Das hier ist falsch
std::size_t log(int n)
        // highest position of 1 bit
{
    std::size_t bits{ 0 };
    while (n) {
        ++bits;
        n &gt;&gt;= 1;
    }
    return bits;
}
bool add_is_safe(int lhs, int rhs)
{
    std::size_t lhsbits = log(lhs);
    std::size_t rhsbits = log(rhs);
    std::size_t total = sizeof(int) * 8;
    return (lhsbits &lt; total &amp;&amp; rhsbits &lt; total);
}
</code></pre>
<p>Das Prinzip würde ich dementsprechend auch auf die anderen Operatoren übertragen...</p>
<p>LG</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/330243/gelöst-overflow-test-integers</link><generator>RSS for Node</generator><lastBuildDate>Fri, 03 Jul 2026 11:35:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/330243.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 30 Dec 2014 11:03:15 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Sat, 03 Jan 2015 11:04:43 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>angenommen ich möchte überprüfen, ob das Addieren von zwei Integern a und b einen overflow erzeugen wird, welche (der beiden) Methode(n) ist besser/sind am besten?</p>
<pre><code>const int maxint = std::numeric_limits&lt;int&gt;::max();
const int minint = std::numeric_limits&lt;int&gt;::min();

bool add_is_safe(int lhs, int rhs)
{
    if (lhs &gt; 0 &amp;&amp; rhs &gt; 0)
        return (lhs &lt;= maxint - rhs);
    else if (lhs &lt; 0 &amp;&amp; rhs &lt; 0)
        return (lhs &gt;= minint + rhs);
    else
        return true;
}
// oder (von StackOverflow)
// ACHTUNG: Das hier ist falsch
std::size_t log(int n)
        // highest position of 1 bit
{
    std::size_t bits{ 0 };
    while (n) {
        ++bits;
        n &gt;&gt;= 1;
    }
    return bits;
}
bool add_is_safe(int lhs, int rhs)
{
    std::size_t lhsbits = log(lhs);
    std::size_t rhsbits = log(rhs);
    std::size_t total = sizeof(int) * 8;
    return (lhsbits &lt; total &amp;&amp; rhsbits &lt; total);
}
</code></pre>
<p>Das Prinzip würde ich dementsprechend auch auf die anderen Operatoren übertragen...</p>
<p>LG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435279</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435279</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Sat, 03 Jan 2015 11:04:43 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 11:30:03 GMT]]></title><description><![CDATA[<p>Wieso meinst du das zu brauchen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435281</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435281</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Tue, 30 Dec 2014 11:30:03 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 11:40:07 GMT]]></title><description><![CDATA[<p>Ich habe eine Klasse, die ca. so aussieht</p>
<pre><code>class Rational {
//...
private:
    int num;
    int denom;
};
</code></pre>
<p>Und da gibt es + - * /.<br />
Ich will eine exception werfen, wenn eine dieser Operationen ein falsches Ergebnis ergeben würde (aufgrund dessen, dass das Ergebis nicht in einen int passt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435282</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435282</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Tue, 30 Dec 2014 11:40:07 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 12:48:42 GMT]]></title><description><![CDATA[<p>Die zweite Version ist falsch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435297</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435297</guid><dc:creator><![CDATA[mgaeckler]]></dc:creator><pubDate>Tue, 30 Dec 2014 12:48:42 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 12:51:50 GMT]]></title><description><![CDATA[<p>mgaeckler schrieb:</p>
<blockquote>
<p>Die zweite Version ist falsch.</p>
</blockquote>
<p>Willst du mir auch erklären warum? Hab das von hier:<br />
<a href="http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c" rel="nofollow">http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435298</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435298</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Tue, 30 Dec 2014 12:51:50 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 12:56:41 GMT]]></title><description><![CDATA[<p>HarteWare schrieb:</p>
<blockquote>
<p>Ich will eine exception werfen, wenn eine dieser Operationen ein falsches Ergebnis ergeben würde (aufgrund dessen, dass das Ergebis nicht in einen int passt.</p>
</blockquote>
<p>Selbe Frage. Signed overflow ist UB. Lass es einfach UB bleiben Bei normalen Integern oder std::complex passiert das ja auch nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435303</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435303</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Tue, 30 Dec 2014 12:56:41 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 13:02:50 GMT]]></title><description><![CDATA[<p>Ich hätt' gerne integers die werfen, wenn sie was nicht können ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435310</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435310</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Tue, 30 Dec 2014 13:02:50 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 13:07:33 GMT]]></title><description><![CDATA[<p>HarteWare schrieb:</p>
<blockquote>
<p>mgaeckler schrieb:</p>
<blockquote>
<p>Die zweite Version ist falsch.</p>
</blockquote>
<p>Willst du mir auch erklären warum? Hab das von hier:<br />
<a href="http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c" rel="nofollow">http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c</a></p>
</blockquote>
<p>log terminiert nicht, wenn es mit einer negativen Zahl aufgerufen wird.</p>
<p>Für positive Werte liefert addissafe immer True. Das ist Unfug.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435313</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435313</guid><dc:creator><![CDATA[mgaeckler]]></dc:creator><pubDate>Tue, 30 Dec 2014 13:07:33 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 13:11:02 GMT]]></title><description><![CDATA[<p>D.h., angenommen ich rechne jetzt zwei dieser Brüche zusammen, dann überlasse ich es dem Anwender zu kapieren, dass das Ergebnis Schwachsinn ist, weil er eben Zahlen so gewählt hat, dass die Brüche zu groß wurden?</p>
<p>Vielleicht habe ich</p>
<pre><code>Überläufe werden nicht vernünftig behandelt; nicht einmal dann, wenn das (normalisierte) Ergebnis exakt darstellbar ist.
</code></pre>
<p>auch einfach nur falsch verstanden, ich mein ist ja nett und gut und alles, dass die Leute mir Tips geben was ich ja auch will, aber da ist so wenig Info dabei, dass ich auch nicht so recht weiß, wo ich das ansetzten soll. Wenn ich so schlau wäre, dass mir das alles gleich klar ist, bräuchte ich die Hilfe ja auch nicht...</p>
<p>Für die Leute, die jetzt hier verwirrt sind, ich habe ein bisschen Code im Projekte Forum gepostet und hab auf Anfrage ein paar Verbesserungsvorschläge erhalten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /> . Ich hab einige schon, so gut ich konnte, umgesetzt, aber bei manchen bin ich mir bei deren Umsetzung unsicher, deshalb z.B. dieser Thread (soll keine Selbstpromotion sein)</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/24458">@mgaeckler</a><br />
verstehe, jetzt ist es mir klar, danke.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435315</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435315</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Tue, 30 Dec 2014 13:11:02 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 13:52:08 GMT]]></title><description><![CDATA[<p>HarteWare schrieb:</p>
<blockquote>
<p>Vielleicht habe ich</p>
<pre><code>Überläufe werden nicht vernünftig behandelt; nicht einmal dann, wenn das (normalisierte) Ergebnis exakt darstellbar ist.
</code></pre>
<p>auch einfach nur falsch verstanden, ich mein ist ja nett und gut und alles, dass die Leute mir Tips geben was ich ja auch will, aber da ist so wenig Info dabei, dass ich auch nicht so recht weiß, wo ich das ansetzten soll.</p>
</blockquote>
<p>Du hast das Problem schon richtig verstanden.<br />
Grundsätzlich muss man sich ja bei Operationen mit Zahlen Gedanken machen, wann die Ergebnisse brauchbar sind. Bin ich als Nutzer in der Situation, dass Rechenergebnisse nicht zuverlässig korrekt sind, stellt sich die Frage,<br />
1. ob das tatsächliche Ergebnis statt dessen brauchbar ist (weil es z.B. eine Näherung darstellt wie bei Gleitkommazahlen),<br />
2. ob der entstehende Überlauf/Inexaktheit ggf. vor Ausführung der Rechnung erkannt und vermieden werden kann,<br />
3. wenigstens ein Fehler kommuniziert wird, damit der Anwender sich nicht auf falsche Daten verlässt.<br />
Nr. 2 ist z.B. für Integer in der Regel vergleichsweise einfach, insbesondere wenn der Wertebereich der Eingangsdaten bekannten Beschränkungen unterliegt.<br />
Dein rational genügt diesen Bedingungen bisher nicht. Die 2. Bedingung ist prinzipbedingt kaum erfüllbar, ein Abbruch per Exception ist folglich naheliegend. Option 1 sollte allerdings auch bedacht werden - zweiffellos hängt es allerdings von der Anwendung ab, ob ggf. Näherungsergebnis akzeptabel sein können. Ist nebenbei mathematisch ein recht interessante Sache (Stichwort Kettenbruchentwicklung).</p>
<p>Praktisch würde ich vorliegenden Fall zunächst intern mit größeren Zahlen arbeiten. Wenn Zähler und Nenner je 32 bit benötigen, können wir sicher sein, das Zwischenergebnisse mit 64bit auskommen. Die Prüfung, ob ein Überlauf vorliegt, kann dann nach dem Normalisieren erfolgen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435337</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435337</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 30 Dec 2014 13:52:08 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 15:41:14 GMT]]></title><description><![CDATA[<p>Hallo nochmals,</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a><br />
vielen Dank für deine Ausführung, das hat mir gleich viel mehr geholfen. Ich habe einen Prototyp für eine Funktion entwickelt, die 2 Rationals versucht zu addieren, und eine Exception wirft, wenn das normalisierte Ergebnis trotzdem überläuft (zumindest macht sie es in der Theorie und in wenigen Testfällen).</p>
<p>Nun frage ich mich, ob das so in Ordnung ist, insbesondere das ganze Gecaste. Jedoch hat es nicht funktionert, als ich Zähler und Nenner nicht nach long long gecasted hab (overflow nicht erkannt, da schon passiert, weil das Ergebnis vermutlich noch als int evaluiert wurde, bevor es in den long long gesteckt wurde). Jedenfalls hab ich das mit 64bit so interpretiert, dass da ein long long her muss/soll/kann. (ich bin auf long long gekommen, da sizeof(long long) bei mir 8 ergibt)</p>
<p>Hab gcd auf unsigned long long übertragen, damit ich auch die long longs normalisieren kann.</p>
<pre><code>Rational safe_add(const Rational&amp; lhs, const Rational&amp; rhs)
{
    long long lnum = static_cast&lt;long long&gt;(lhs.num);
    long long rnum = static_cast&lt;long long&gt;(rhs.num);
    long long lden = static_cast&lt;long long&gt;(lhs.denom);
    long long rden = static_cast&lt;long long&gt;(rhs.denom);

    long long n = lnum*rden + lden*rnum;
    long long d = lden * rden;

    // kürzen
    long long div = gcd(std::abs(n), std::abs(d));
    if (div &gt; 1) {
        n /= div;
        d /= div;
    }

    if (n &gt; maxint || d &gt; maxint || n &lt; minint || d &lt; minint)
        throw std::runtime_error(&quot;Overflow while adding two rationals.&quot;);
    return Rational{ static_cast&lt;int&gt;(n), static_cast&lt;int&gt;(d) };
}
</code></pre>
<p>Das Ganze könnte ich ja dann so benutzen:</p>
<pre><code>Rational&amp; operator+=(const Rational&amp; rhs)
{
    return *this = safe_add(*this, rhs);
}
</code></pre>
<p>Vielleicht sollte ich Zähler und Nenner einfach public machen, das würde einige 'friend' Funktionen ersparen...</p>
<p>Der Sache mit einen Bruch finden, der eventuell den theoretisch nicht Akzeptierten so annähert, dass man stattdessen diesen verwenden kann, werde ich mich anschließend widmen.<br />
Vielleicht ist das auch etwas änhliches, wie volkard mit dem brocot-stern-baum meinte (zumindest hab ich bei der Recherche gemeint da Parallelen zur Kettenbruchentwicklung zu finden).</p>
<p>P.S.: Mir fällt grad so auf, wenn ich jetzt nicht eine Option einbaue, dass man das verwenden der Kettenbruchentwicklung abstellen kann (würde ich vermutlich schon), dann würde es doch praktisch nie zu Overflows kommen, oder?<br />
Ich mein, zu diesen riesigen Zählern und Nennern komme ich ja durch meinen momentanen naiven algo, der im Prinzip für jede Stelle die nächsthöhere Zehnerpotenz in den Nenner knallt, im Zähler wird die Zahl dementsprechend auch groß.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435354</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435354</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Tue, 30 Dec 2014 15:41:14 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Tue, 30 Dec 2014 17:38:00 GMT]]></title><description><![CDATA[<p>falls das nicht allzu resourcen-kritisch ist, was du da mit den Brüchen vorhast, könnte man eine bignum library benutzen. Dann stellt sich das Problem erst gar nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435387</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435387</guid><dc:creator><![CDATA[großbuchstaben]]></dc:creator><pubDate>Tue, 30 Dec 2014 17:38:00 GMT</pubDate></item><item><title><![CDATA[Reply to [Gelöst] Overflow Test - Integers on Sat, 03 Jan 2015 11:07:45 GMT]]></title><description><![CDATA[<p>die Funktion safe_add ist ja recht groß und Umfangreich. Würde es sich lohnen, einen check noch einzubauen, der nur safe_add verwendet, falls es so mit Integern zum Overflow kommen würde?:</p>
<pre><code>bool mul_is_safe(int lhs, int rhs)
{
    if (lhs &gt; maxint / rhs || lhs &lt; minint / rhs)
        return false;

    return true;
}

Rational&amp; operator+=(const Rational&amp; rhs)
{
    if (!mul_is_safe(*this.num, rhs.denom) ||
        !mul_is_safe(*this.denom, rhs.num) ||
        !mul_is_safe(*this.denom, rhs.denom)) {
                return *this = safe_add(*this, rhs);
     } else {
         this-&gt;num = this-&gt;num*rhs.denom + this-&gt;denom*rhs.num;
         this-&gt;denom *= rhs.denom;
         this-&gt;reduce();
         return *this;
    }
}
</code></pre>
<p>Oder schenkt sich dadurch, dass 3 Mal mul_is_safe aufgerufen wird nicht viel?</p>
<p>hhmm keiner antwortet. Jetzt stellt sich die Frage wieso...<br />
Zu unkonkret?<br />
Bin ich sowieso komplett falsch?<br />
Ist die Frage doof?<br />
Wurde sie schonmal irgendwo beantwortet und ich habs übersehen?<br />
Versteht keiner, was ich da mache(n) (will)?</p>
<p>Ich finde das frustrierend. Aber egal. Ich hab 2 Bücher, das Internet, und meinen hoffentlich gesunden Menschenverstand. Das werd ich wohl irgendwie auch alleine hinbekommen.</p>
<p>Bis dahin kann ich ja mal mich auf Anderes konzentrieren, z.B. Anwendung des brocot-stern-baums bzw der Kettenbruchentwicklung bei double-to-Rational</p>
<p><strong>Edit:</strong> Ich hab grad auf die harte Tour einen Bug in der Funktion gefunden. Die sieht nämlich echt alt aus, wenn ich mit 0 multiplizieren möchte.<br />
Jetzt muss ich überlegen, wie ich das behandle. Habs mir mal so überlegt:</p>
<pre><code>bool mul_is_safe(int lhs, int rhs)
{
    if (!lhs || !rhs) return true;
    if (lhs &gt; maxint / rhs || lhs &lt; minint / rhs) return false;
    return true;
}
</code></pre>
<p>Das ist denke ich gut begründet, da eine Multiplikation mit 0 immer 0 ergibt.</p>
<p>Also ich habe die Botschaft, dass hier niemand mehr schreibt, angenommen und entcheide das einfach selbst.</p>
<p>Ich hab nochmal über das nachgedacht, was Nathan gesagt hat, ich kann ja einen Integer Overflow provozieren und wenn ich das Programm starte crasht es auch nicht gleich.</p>
<p>Wenn das dann mit std::complex auch so ist, dann bin ich mir in meiner Entscheidung eigentlich ziemlich sicher: Die normalen Operatoren lass ich jetzt &quot;unsicher&quot;. Aber ich lass mal die Funktionen drin, mit denen man &quot;sicher&quot; Addieren etc. kann.<br />
Da ich mich schon etwas in diese Kettenbruchentwicklung eingearbeitet habe, werde ich versuchen das noch in diese Funktionen einzubauen, dass sie bei passendem bool Wert einen Bruch ausgeben, der näherungsweise das gleiche Ergebnis ist, aber halt nicht overflowed.<br />
Das scheint für mich vorerst mal das Vernünftige zu sein, und ist ca. die Mitte zwischen den beiden Prinzipien.<br />
In dem Fall ist das Thema für mich gegessen, danke an alle <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/2435561</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435561</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Sat, 03 Jan 2015 11:07:45 GMT</pubDate></item></channel></rss>