<?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[Schnelle Rundungsfunktion]]></title><description><![CDATA[<p>Hi,</p>
<p>bisher benutze ich zum Runden von double's folgendes Macro:</p>
<pre><code>MY_ROUND(inVal,numDig) (((double)(int)((inVal)*pow((double)10,numDig)+CNCO_SIGN(inVal)*0.5))/pow((double)10,numDig))
</code></pre>
<p>inVal ist der zu rundende Wert, numDig legt die Anzahl der Nachkommastellen fest, auf die gerundet werden soll.</p>
<p>Dank der pow()'s und Divisionen ist das Makro natürlich nicht sehr schnell. Deswegen meine Frage: welche Alternativen gibt es hier? Eventuell eine schnelle Funktion aus dem C++-Standard? Oder ein besserer Ersatz für mein Macro?</p>
<p>Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/339538/schnelle-rundungsfunktion</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 23:19:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/339538.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 07 Sep 2016 11:23:51 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 07 Sep 2016 11:23:51 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>bisher benutze ich zum Runden von double's folgendes Macro:</p>
<pre><code>MY_ROUND(inVal,numDig) (((double)(int)((inVal)*pow((double)10,numDig)+CNCO_SIGN(inVal)*0.5))/pow((double)10,numDig))
</code></pre>
<p>inVal ist der zu rundende Wert, numDig legt die Anzahl der Nachkommastellen fest, auf die gerundet werden soll.</p>
<p>Dank der pow()'s und Divisionen ist das Makro natürlich nicht sehr schnell. Deswegen meine Frage: welche Alternativen gibt es hier? Eventuell eine schnelle Funktion aus dem C++-Standard? Oder ein besserer Ersatz für mein Macro?</p>
<p>Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2507827</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2507827</guid><dc:creator><![CDATA[Morom]]></dc:creator><pubDate>Wed, 07 Sep 2016 11:23:51 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 07 Sep 2016 12:17:17 GMT]]></title><description><![CDATA[<p>Da mit CNCO_SIGN unbekannt ist, habe ich einfach mal danach gesucht. Google findet lustigerweise genau einen Treffer - nämlich genau dieselbe Frage auf SO: <a href="https://stackoverflow.com/questions/39368809/fast-rounding-function-with-variable-precision" rel="nofollow">https://stackoverflow.com/questions/39368809/fast-rounding-function-with-variable-precision</a></p>
<p>Mir fallen Fragen ein:<br />
a) warum nicht als Funktion statt als Macro?<br />
b) dieses ganze rumgecaste: was, wenn der int-Wert nicht in double passt?<br />
c) was soll eigentlich genau erreicht werden? Was soll der Ausgabetyp sein? Etwa double, der ggf. das gerundete Ergebnis nicht exakt darstellen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2507832</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2507832</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Wed, 07 Sep 2016 12:17:17 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 07 Sep 2016 12:20:36 GMT]]></title><description><![CDATA[<p>Argh, b) war natürlich auch umgekehrt gültig: was, wenn der double-Wert nicht in int passt? Welche Typen/Werte sollen überhaupt für inVal und numDig eingesetzt werden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2507833</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2507833</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Wed, 07 Sep 2016 12:20:36 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 07 Sep 2016 12:38:45 GMT]]></title><description><![CDATA[<p>stellt sich noch die Frage: warum überhaupt im Dezimalsystem runden. Dies ist nämlich für einen beliebiegen <code>double</code> i.A. gar nicht möglich. So ist z.B. die Zahl 0,1 im Binärsystem mit endlicher Anzahl von Nachkommastellen gar nicht darstellbar.<br />
Wenn Du schreibst</p>
<pre><code>double a = 0.1;
</code></pre>
<p>so enthält 'a' einen Wert von etwa 0.10000000000000001. Die nächst kleinere Zahl im Bereich double (8 Byte) müßte so bei 0.099999999999999992 liegen. Dazwischen gibt es schlicht nichts. Was willst Du da also runden?</p>
<p>Wenn das Runden nur die Ausgabe betrifft, so greife auf die Mittel zurück, die die Ausgabefunktionen bieten. Das ist dann auch viel schneller.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2507834</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2507834</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Wed, 07 Sep 2016 12:38:45 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 07 Sep 2016 13:01:47 GMT]]></title><description><![CDATA[<p>Warum nicht so?</p>
<pre><code>#include &lt;cmath&gt;

#include &lt;iostream&gt;

constexpr double operator &quot;&quot; _digits(unsigned long long n)
{
	return std::pow(10., n);
}

constexpr double round(double n, double factor)
{
	return std::round(n * factor) / factor;
}

int main()
{
	double const almost_pi = 3.1415927;
	std::cout &lt;&lt; round(almost_pi, 2_digits) &lt;&lt; std::endl;
	return 0;
}
</code></pre>
<p>Generell auch zu dem Makro:<br />
pow (bzw. std::pow) könnte ab C++11 constexpr sein,<br />
auch wenn ich dazu auf cppreference nichts finden konnte...<br />
Der GCC macht es jedenfalls <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="🙂"
    /><br />
Damit kann bei einer zur Compile-Time bekannten Rundung schonmal das potenzieren rausoptimiert und durch einen konstanten Wert ersetzt werden.</p>
<p>Danach hast du eigentlich nur noch Multiplikationen und Divisionen.<br />
Die fliegen auch raus, wenn dein Eingabewert auch zur Compile-Time bekannt ist.</p>
<p>Davon abgesehen ist die moderne Variante trotzdem aus mehreren Gründen zu bevorzugen:</p>
<ul>
<li>Kein Makro! (Makros haben keinen direkten Scope und verschmutzen im Grunde die ganze Übersetzungseinheit)</li>
<li>Dein Makro wertet seine Parameter mehrfach aus, was besonders doof ist, wenn jemand als Parameter sowas wie &quot;foo++&quot; angibt.</li>
<li>Durch den nutzerdefinierten Literal wird auch direkt deutlich, was die Parameter tun: 1. welcher Wert gerundet wird, 2. auf wie viele Nachkommastellen</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/2507837</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2507837</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Wed, 07 Sep 2016 13:01:47 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Tue, 13 Sep 2016 11:09:52 GMT]]></title><description><![CDATA[<p>Um das mal zu erklären: ich verwende die Rundungsfunktion, um z.B. Vergleiche mit begrenzter Genauigkeit durchzuführen.</p>
<p>Wenn z.B. zwei double-Werte 6.12349684731 und 6.12348874662 vorkommen, so sind diese nicht gleich. Jetzt benötige ich aber nur eine Genauigkeit von 4 Nachkommastellen, also runde ich die beiden Werte nach 6.1235 und 6.1235 -&gt; sie sind gleich. Wenn mir double auf Grund seiner Beschränkungen da jetzt aber beispielsweise 6.12349999999 und 6.12349999999 draus macht, ist mir das auch egal, weil der Vergleich in dem Falle auch wieder ergibt, dass sie gleich sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508476</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508476</guid><dc:creator><![CDATA[Morom]]></dc:creator><pubDate>Tue, 13 Sep 2016 11:09:52 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Tue, 13 Sep 2016 11:36:18 GMT]]></title><description><![CDATA[<p>Was spricht dann dagegen, einfach die Differenz zu bilden?</p>
<pre><code>auto d1 = 6.12349684731;
auto d2 = 6.12348874662;
std::abs(d1-d2)
(double) 8.10069e-06
std::abs(d1-d2) &lt; 0.0001
(bool) true
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2508479</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508479</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Tue, 13 Sep 2016 11:36:18 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Tue, 13 Sep 2016 11:50:54 GMT]]></title><description><![CDATA[<p>Die Genauigkeit hängt nicht von den Nachkommastellen<sup>1</sup> ab, sondern von den signifikanten Stellen.</p>
<p><sup>1</sup>Bei der Exponentialschreibweise kann man die Nachkommstellen betrachten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508480</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508480</guid><dc:creator><![CDATA[DirkB]]></dc:creator><pubDate>Tue, 13 Sep 2016 11:50:54 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Tue, 13 Sep 2016 15:28:46 GMT]]></title><description><![CDATA[<p>Das was DirkB sagt. Aber noch mit der Ergänzung, dass auch das nicht reicht. Die dumme 0 macht alles kaputt und es gibt noch weitere mögliche Komplikationen. Das ganze Thema ist schwierig (und zwar <strong>sehr viel</strong> schwieriger, als der TE denkt!) und es gibt leider keine zufriedenstellenden Lösungen, die wirklich alle Fälle abdecken. Siehe hier für eine Abhandlung:<br />
<a href="https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/" rel="nofollow">https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/</a></p>
<p>Noch eine interessante Lösung technischer Art: Nach IEEE 754 ist die Integer-Repräsentation von Fließkommazahlen geordnet. Wenn man sich also darauf verlassen kann, dass die Maschine diesen Standard benutzt (kann man zu 99.9999%) und man hat Zugriff auf diese Repräsentation (in C++ kein Problem), dann kann man sich ausrechnen, um wie viele float-&quot;Schritte&quot; sich zwei Werte unterscheiden und danach ein Vergleichskriterium bauen. Das Problem mit der 0 bleibt jedoch bestehen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508514</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508514</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 13 Sep 2016 15:28:46 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 14 Sep 2016 12:47:51 GMT]]></title><description><![CDATA[<p>Morom schrieb:</p>
<blockquote>
<p>Wenn z.B. zwei double-Werte 6.12349684731 und 6.12348874662 vorkommen, so sind diese nicht gleich. Jetzt benötige ich aber nur eine Genauigkeit von 4 Nachkommastellen, also runde ich die beiden Werte nach 6.1235 und 6.1235 -&gt; sie sind gleich.</p>
</blockquote>
<p>nach dem Verfahren wären 6.12346 und 6.12354 gleich, aber 6.12346 und 6.12344 wären nicht gleich, obwohl ihre Differenz nur 1/4 von der Differenz des ersten Zahlenpaars ausmacht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508684</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508684</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Wed, 14 Sep 2016 12:47:51 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 14 Sep 2016 13:19:44 GMT]]></title><description><![CDATA[<blockquote>
<p>Vergleiche mit begrenzter Genauigkeit</p>
</blockquote>
<p>Wie wärs damit?</p>
<pre><code>bool is_almost_equal(double a, double b, double prec=0.0001)
{
    return abs(a-b) &lt;= prec; // ?
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2508688</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508688</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Wed, 14 Sep 2016 13:19:44 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 14 Sep 2016 14:33:04 GMT]]></title><description><![CDATA[<p>Ist halt die Frage, ob 1e-7 und 1e-17 wirklich als gleich gelten sollen, obwohl 10 Größenordnungen (und ca 1.5e17 potentielle double-Werte) dazwischen liegen.</p>
<p>Oder ob 1.00001 und 1000002 wirklich als gleich gelten sollen, während 100000000000001 und 100000000000002 als verschieden gelten (obwohl da nur 64 andere Werte zwischen gehen!).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508693</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508693</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 14 Sep 2016 14:33:04 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 14 Sep 2016 15:59:50 GMT]]></title><description><![CDATA[<p>Ja, das ist alles nicht so einfach.<br />
Ich weiss auch gar nicht ob man überhaupt eine richtig schnelle (und gleichzeitig schlaue) Epsilon-Equals Funktion machen kann. Also z.B. eine wo Epsilon ein vielfaches der &quot;Unit in the Last Place&quot; (ULP) ist.<br />
Wenn's auch langsam sein darf, dann ist es nicht so schwer. ULP der grösseren Zahl ermitteln, mit Konstante multiplizieren, und dann gucken ob die Differenz der beiden Zahlen betragsmässig kleiner ist.</p>
<p>@Morom<br />
Muss dein Test auf &quot;Gleichheit&quot; transitiv sein?<br />
Wenn nein, dann bietet sich eine Epsilon-Equals Funktion mit manuellem Epsilon an, so wie <code>wob</code> bzw. <code>HarteWare</code> es vorgeschlagen haben.</p>
<p>Und wenn du eine transitive Funktion brauchst, dann ist vermutlich Runden eh die beste Lösung. Nur würde ich, wenns geht, auf binäre Stellen runden und nicht auf dezimale.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508698</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508698</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 14 Sep 2016 15:59:50 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Wed, 14 Sep 2016 16:32:40 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Ja, das ist alles nicht so einfach.<br />
Ich weiss auch gar nicht ob man überhaupt eine richtig schnelle (und gleichzeitig schlaue) Epsilon-Equals Funktion machen kann. Also z.B. eine wo Epsilon ein vielfaches der &quot;Unit in the Last Place&quot; (ULP) ist.<br />
Wenn's auch langsam sein darf, dann ist es nicht so schwer. ULP der grösseren Zahl ermitteln, mit Konstante multiplizieren, und dann gucken ob die Differenz der beiden Zahlen betragsmässig kleiner ist.</p>
</blockquote>
<p>Die schnelle Methode dafür habe ich doch schon genannt. Nach int casten, Differenz bilden, mit Vorgabe vergleichen. Funktioniert auf jeder IEEE 754 Maschine. Eventuell noch Sonderbehandlung für NaN, inf, usw. einführen.</p>
<p>Problem ist halt, dass solch ein flexibler epsilon-Vergleich nicht mit der häufig gewünschten Funktionalität kompatibel ist, unter einer gewissen Schranke alles als 0 anzusehen. Da muss man dann wieder eine Sonderprüfung einbauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508699</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 14 Sep 2016 16:32:40 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Thu, 15 Sep 2016 06:03:10 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>so wie <code>wob</code> bzw. <code>HarteWare</code> es vorgeschlagen haben.</p>
</blockquote>
<p>Ach, ich Blindfisch! Habe diesen kleinen Code-Snippet voll übersehen. War natürlich nicht meine Absicht alles zwei Mal zu sagen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508724</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508724</guid><dc:creator><![CDATA[HarteWare]]></dc:creator><pubDate>Thu, 15 Sep 2016 06:03:10 GMT</pubDate></item><item><title><![CDATA[Reply to Schnelle Rundungsfunktion on Thu, 15 Sep 2016 23:41:43 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a><br />
Womit wir wieder beim Thema &quot;scheiss strict aliasing&quot; wären <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2508791</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2508791</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 15 Sep 2016 23:41:43 GMT</pubDate></item></channel></rss>