<?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[Division mit Rest bei großen unsigned Integer]]></title><description><![CDATA[<p>Hallo!</p>
<p>ich brauche mal etwas Hilfe. Und zwar programmiere ich derzeit eine Klasse, die große (unsigned) Integer speichern und verarbeiten kann.<br />
Addition, Subtraktion, Multiplikation hab ich schon, habe mich da meistens nach &quot;The art of computer programming&quot; von Donald Knuth gerichtet.<br />
Die Division bekomme ich aber einfach nicht hin.<br />
Ich brauche irgendwas das schneller ist als</p>
<pre><code>XInt slowdiv(const XInt&amp; a, const XInt&amp; b, XInt&amp; r) {
    XInt q(XInt::xIntZero);
    r=a;
    while(isGeq(r,b))
    {
        r -= b;
        q++;
    }
    return q;
}
</code></pre>
<p>Die Zahlen sind dabei durch ihre Dezimalziffern in einem int-Array gespeichert.</p>
<p>Bitte gebt mir ein paar Tips, wie ich es wenigstens etwas effizienter implementieren kann, der Algorithmus von Knuth will bei mir einfach nicht funktionieren!<br />
Ich hoffe es kann mir jemand helfen, ich bin langsam am verzweifeln.</p>
<p>Viele Grüße</p>
<p>Edit: Ich habe mir GMP und ähnliche Bibliotheken schon angesehen, allerdings ist es die Aufgabe, es selbst zu implementieren. Die meisten Funktionen davon brauche ich auch nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/237557/division-mit-rest-bei-großen-unsigned-integer</link><generator>RSS for Node</generator><lastBuildDate>Wed, 23 Sep 2026 06:23:08 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/237557.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 30 Mar 2009 16:29:17 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Mon, 30 Mar 2009 17:01:01 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>ich brauche mal etwas Hilfe. Und zwar programmiere ich derzeit eine Klasse, die große (unsigned) Integer speichern und verarbeiten kann.<br />
Addition, Subtraktion, Multiplikation hab ich schon, habe mich da meistens nach &quot;The art of computer programming&quot; von Donald Knuth gerichtet.<br />
Die Division bekomme ich aber einfach nicht hin.<br />
Ich brauche irgendwas das schneller ist als</p>
<pre><code>XInt slowdiv(const XInt&amp; a, const XInt&amp; b, XInt&amp; r) {
    XInt q(XInt::xIntZero);
    r=a;
    while(isGeq(r,b))
    {
        r -= b;
        q++;
    }
    return q;
}
</code></pre>
<p>Die Zahlen sind dabei durch ihre Dezimalziffern in einem int-Array gespeichert.</p>
<p>Bitte gebt mir ein paar Tips, wie ich es wenigstens etwas effizienter implementieren kann, der Algorithmus von Knuth will bei mir einfach nicht funktionieren!<br />
Ich hoffe es kann mir jemand helfen, ich bin langsam am verzweifeln.</p>
<p>Viele Grüße</p>
<p>Edit: Ich habe mir GMP und ähnliche Bibliotheken schon angesehen, allerdings ist es die Aufgabe, es selbst zu implementieren. Die meisten Funktionen davon brauche ich auch nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1688332</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1688332</guid><dc:creator><![CDATA[Athene]]></dc:creator><pubDate>Mon, 30 Mar 2009 17:01:01 GMT</pubDate></item><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Mon, 30 Mar 2009 17:01:15 GMT]]></title><description><![CDATA[<p><a href="http://de.wikipedia.org/wiki/Euklidischer_Algorithmus" rel="nofollow">http://de.wikipedia.org/wiki/Euklidischer_Algorithmus</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1688341</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1688341</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 30 Mar 2009 17:01:15 GMT</pubDate></item><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Mon, 30 Mar 2009 17:18:37 GMT]]></title><description><![CDATA[<p>Ehrlich gesagt sehe ich nicht, was du mir mit dem Link sagen möchtest bzw wie ich damit eine effiziente Berechnung des Quotienten und des Restes implementieren könnte?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1688350</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1688350</guid><dc:creator><![CDATA[Athene]]></dc:creator><pubDate>Mon, 30 Mar 2009 17:18:37 GMT</pubDate></item><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Mon, 30 Mar 2009 17:22:26 GMT]]></title><description><![CDATA[<p>Sorry, mir war so, als könnte man damit auch den Divisionsrest berechnen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1688351</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1688351</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 30 Mar 2009 17:22:26 GMT</pubDate></item><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Tue, 31 Mar 2009 07:11:37 GMT]]></title><description><![CDATA[<p>Ich weiß nicht ob die Idee sinnvoll ist aber wenn man sich die Zahlen Binär ansieht.</p>
<pre><code>123123756861160068415
1101010110010101111011101001000011100010001000000101001010100111111
/
19
10011

Zählt man die Anzahl der Binärstellen die 19 kleiner ist.
1101010110010101111011101001000011100010001000000101001010100111111
0000000000000000000000000000000000000000000000000000000000000010011
= 62 stellen

Dann schiftet man die 19 62 stellen nach links (was einem 19*2^62 gleichkommt)
= 87622034350120370176

Testen ob resultierende zahl größer ist
Nein -&gt; subtraktion
Ja -&gt; 19 nur um 61 stellen shiften

in unserem fall -&gt; nein
123123756861160068415 - 87622034350120370176 = 35501722511039698239
-&gt; 11110110010101111011101001000011100010001000000101001010100111111
   00000000000000000000000000000000000000000000000000000000000010011

60 stellen
19 um 60 stellen shiften
= 21905508587530092544 &gt; 35501722511039698239 ? -&gt; nein

35501722511039698239 - 21905508587530092544 = 13596213923509605695
-&gt; 1011110010101111011101001000011100010001000000101001010100111111
   0000000000000000000000000000000000000000000000000000000000010011
59 Stellen

19 um 59 stellen shiften
= 10952754293765046272 &gt; 13596213923509605695 ? -&gt; nein

13596213923509605695 - 10952754293765046272 = 2643459629744559423
-&gt; 10010010101111011101001000011100010001000000101001010100111111
   00000000000000000000000000000000000000000000000000000000010011
57 stellen

...

Quotient = 2^62 + 2^60 + 2^59 + 2^57 + ...
</code></pre>
<p>Bei dieser Methode hat man im schlimmsten Fall:</p>
<pre><code>0xFF = 255 = 11111111
/
0x01 =   1 = 1
</code></pre>
<p>Was 8 Schleifendurchgänge wären. Ist also im schlimmsten Fall immer noch um das 32 fache schneller als subtrahieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> (was 256 Schleifendurchgänge wären)</p>
<p>Eine bessere Lösung fällt mir jetzt nicht ein (gibts aber sicher)</p>
<p>Keros</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1688558</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1688558</guid><dc:creator><![CDATA[Keros]]></dc:creator><pubDate>Tue, 31 Mar 2009 07:11:37 GMT</pubDate></item><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Thu, 02 Apr 2009 18:41:16 GMT]]></title><description><![CDATA[<p>Für die Binäroperationen müsste ich alle Zahlen (die ja gerne mal 100 Dezimalstellen haben können) erst transformieren.</p>
<p>Ich habe versucht, den Algorithmus von Seite 60 aus dem Buch &quot;A Computational Introduction to Number Theory and Algebra&quot; von <a href="http://shoup.net/ntb/" rel="nofollow">http://shoup.net/ntb/</a> zu implementieren, allerdings funktioniert es überhaupt nicht, wäre vielleicht jemand so nett, und könnte mal drüber sehen?</p>
<p>Hier meine Implementation:</p>
<pre><code class="language-cpp">// division with remainder
// cf. Shoup: &quot;A computational introduction to number theory and algebra&quot;
XInt div1(const XInt&amp; a1, const XInt&amp; b1, XInt&amp; r) {
    XInt q, a(a1), b(b1);
    int carry = 0, tmp = 0;
    int rdC, qdC, d, base = 10;
    if(isGreater(b,a))
    {
        q = XInt::xIntZero;
        r = a;
        return q;
    }
    if(q.digitCount &lt; a.digitCount+2)
        q.setLength(a.digitCount+2);
    if(r.digitCount &lt; a.digitCount+2)
        r.setLength(a.digitCount+2);

// normalize: b_(n-1) &gt;= base/2
    d = 1;
    while(b.digits[b.digitCount-1]*d &lt; base/2)
    {
        d++;
    }
    b *= d;
    a *= d;

    for(int i=0; i&lt;a.digitCount; i++)
        r.digits[i] = a.digits[i];
    r.digits[a.digitCount] = 0;
    for(int i=a.digitCount-b.digitCount; i&gt;=0; i--)
    {
        q.digits[i] = (int)((r.digits[i+b.digitCount]*base + r.digits[i+b.digitCount-1]) / b.digits[b.digitCount-1]);
        if(q.digits[i] &gt;= base);
            q.digits[i] = base-1;
        carry = 0;
        for(int j=0; j&lt;b.digitCount; j++)
        {
            tmp = r.digits[i+j] - (q.digits[i]*b.digits[j]) + carry;
            carry = tmp/base;
            r.digits[i+j] = tmp%base;
        }
        r.digits[i+b.digitCount] += carry;
        while (r.digits[i+b.digitCount] &lt; 0)
        {
            carry = 0;
            for(int j=0; j&lt;b.digitCount; j++)
            {
                tmp = r.digits[i+j] + b.digits[j] + carry;
                carry = tmp/base;
                r.digits[i+j] = tmp%base;
            }
            r.digits[i+b.digitCount] += carry;
            q.digits[i] -= 1;
        }
    }

    //to do: unnormalize remainder

    //calculate digitCount
    rdC = r.digitCount;
    qdC = q.digitCount;
    r.digitCount = 1; //b.digitCount;
    q.digitCount = 1; //a.digitCount-b.digitCount;
    for(int i=rdC-1; i&gt;=0; i--)
        if(r.digits[i] != 0)
        {
            r.digitCount = i+1;
        }
    for(int i=qdC-1; i&gt;=0; i--)
        if(q.digits[i] != 0)
        {
            q.digitCount = i+1;
        }
    r.digitCount = b.digitCount;

    return q;
}
</code></pre>
<p>Vielen Dank schonmal und schöne Grüße!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1690057</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1690057</guid><dc:creator><![CDATA[Athene]]></dc:creator><pubDate>Thu, 02 Apr 2009 18:41:16 GMT</pubDate></item><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Thu, 02 Apr 2009 19:36:51 GMT]]></title><description><![CDATA[<p>Viel zu viel Code mit viel zu viel nichtssagendem Zeug. Ergo: Niemand wird es sich ansehen.</p>
<p>Mein Tipp: Gehe den Algorithmus mit einfachen Zahlen auf dem Papier durch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1690102</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1690102</guid><dc:creator><![CDATA[The-Kenny]]></dc:creator><pubDate>Thu, 02 Apr 2009 19:36:51 GMT</pubDate></item><item><title><![CDATA[Reply to Division mit Rest bei großen unsigned Integer on Thu, 02 Apr 2009 21:11:16 GMT]]></title><description><![CDATA[<p>Athene schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Zwar schön das du dir so Mühe gegeben hast, aber keine Sau, wie The-Kenny schon meinte, wird sich das anschauen. Ich hab nur drüber gescrollt und hab fast das, entschuldigung für meine Ausdruckweise, gekotzt, weil das einfach zu kryptisch aussieht und man erstmal Minuten lang brauch, ein paar Zeilen zu verstehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1690163</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1690163</guid><dc:creator><![CDATA[freaky]]></dc:creator><pubDate>Thu, 02 Apr 2009 21:11:16 GMT</pubDate></item></channel></rss>