<?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[std::ceil + divide + templates]]></title><description><![CDATA[<p>Zu allererst mal:<br />
für die, die es nicht aus dem kopf wissen: std::ceil ist das <strong>auf</strong>runden</p>
<p>Jz erst mal hallo und Begrüßung und so^^</p>
<p>Ich habe ein Funktionstemplate und muss in diesem Runden und Dividieren - vereinfacht sieht das ganze so aus:</p>
<pre><code class="language-cpp">template &lt;typename t1, typename t2, typename t3&gt;
t1 name(t2 a, t3 b)
{
  return std::ceil (a / b);
}
</code></pre>
<p>Kein Problem, solange a oder b floats sind - aber wie würdet ihr das schreiben, damit es immer funktioniert?<br />
Folgendes kann ich beim Aufruf garantieren:</p>
<ul>
<li>a ist positiv, muss aber nicht zwangsläufig unsigned sein</li>
<li>b ist positiv, muss aber nicht zwangsläufig unsigned sein</li>
<li>-&gt; das zu rundende Ergebnis ist positiv</li>
<li>da t1 ein typedef auf einen size_type ist, wird es vermutlich size_t sein - auf jedenfall ein vorzeichenloser Typ</li>
</ul>
<p>Meine alternative Idee wäre so etwas gewesen:</p>
<pre><code class="language-cpp">template &lt;typename t1, typename t2, typename t3&gt;
t1 name(t2 a, t3 b)
{
  return (a+b-1) / b; // (a+b-1)/b == a/b + 1 - 1/b
}
</code></pre>
<p>Ich nutze sie zur Zeit auch und es sieht auch so aus, als würden die Ergebnisse stimmen. Aber so richtig gefallen tut mir das auch wieder nicht - weil ich mir nicht ganz sicher bin, ob es _immer_ geht und auch nicht so richtig auf ne Beweis-Idee komme.</p>
<p>Sagt einfach mal, wie ihr es machen würdet...<br />
Und falls ihr Fragen habt, dann fragt eben - bevor die Frage nach dem Warum kommt:<br />
Das Ergebnis brauche ich, um zu wissen, wie viele Elemente ich in ein Array pushen muss - die beiden Parameter sind Transport-Kapazitäten, die aber auch ein signed typedef haben könnten - hier aber trotzdem immer positiv sind.</p>
<p>Was ich eigtl nicht unbedingt möchte, ist einfach rumzu casten ^^</p>
<p>Ist ziemlich lang geworden, aber ich denke dafür wenigsten ganz gut beschrieben ^^</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/235867/std-ceil-divide-templates</link><generator>RSS for Node</generator><lastBuildDate>Thu, 24 Sep 2026 03:27:05 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/235867.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 07 Mar 2009 16:51:13 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to std::ceil + divide + templates on Sat, 07 Mar 2009 16:51:13 GMT]]></title><description><![CDATA[<p>Zu allererst mal:<br />
für die, die es nicht aus dem kopf wissen: std::ceil ist das <strong>auf</strong>runden</p>
<p>Jz erst mal hallo und Begrüßung und so^^</p>
<p>Ich habe ein Funktionstemplate und muss in diesem Runden und Dividieren - vereinfacht sieht das ganze so aus:</p>
<pre><code class="language-cpp">template &lt;typename t1, typename t2, typename t3&gt;
t1 name(t2 a, t3 b)
{
  return std::ceil (a / b);
}
</code></pre>
<p>Kein Problem, solange a oder b floats sind - aber wie würdet ihr das schreiben, damit es immer funktioniert?<br />
Folgendes kann ich beim Aufruf garantieren:</p>
<ul>
<li>a ist positiv, muss aber nicht zwangsläufig unsigned sein</li>
<li>b ist positiv, muss aber nicht zwangsläufig unsigned sein</li>
<li>-&gt; das zu rundende Ergebnis ist positiv</li>
<li>da t1 ein typedef auf einen size_type ist, wird es vermutlich size_t sein - auf jedenfall ein vorzeichenloser Typ</li>
</ul>
<p>Meine alternative Idee wäre so etwas gewesen:</p>
<pre><code class="language-cpp">template &lt;typename t1, typename t2, typename t3&gt;
t1 name(t2 a, t3 b)
{
  return (a+b-1) / b; // (a+b-1)/b == a/b + 1 - 1/b
}
</code></pre>
<p>Ich nutze sie zur Zeit auch und es sieht auch so aus, als würden die Ergebnisse stimmen. Aber so richtig gefallen tut mir das auch wieder nicht - weil ich mir nicht ganz sicher bin, ob es _immer_ geht und auch nicht so richtig auf ne Beweis-Idee komme.</p>
<p>Sagt einfach mal, wie ihr es machen würdet...<br />
Und falls ihr Fragen habt, dann fragt eben - bevor die Frage nach dem Warum kommt:<br />
Das Ergebnis brauche ich, um zu wissen, wie viele Elemente ich in ein Array pushen muss - die beiden Parameter sind Transport-Kapazitäten, die aber auch ein signed typedef haben könnten - hier aber trotzdem immer positiv sind.</p>
<p>Was ich eigtl nicht unbedingt möchte, ist einfach rumzu casten ^^</p>
<p>Ist ziemlich lang geworden, aber ich denke dafür wenigsten ganz gut beschrieben ^^</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1675782</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1675782</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Sat, 07 Mar 2009 16:51:13 GMT</pubDate></item><item><title><![CDATA[Reply to std::ceil + divide + templates on Sat, 07 Mar 2009 17:56:54 GMT]]></title><description><![CDATA[<p>1. Wieso können es verschiedene Typen sein?<br />
2. Bei Integer Typen wird deine Funktion wohl kaum das machen, was du willst. Für a / b, wenn a und b ein Integertyp sind, dann wird das Ergebnis abgeschnitten, bevor es an die Funktion geht.<br />
Wenn es wirklich für alle Typen sein soll, dann würde ich sowas machen:</p>
<pre><code class="language-cpp">#include &lt;boost/type_traits/is_floating_point.hpp&gt;

// ...

template&lt;typename ResultT, typename T1, typename T2&gt;
ResultT foo(T1 lhs, T2 rhs)
{
  if(boost::is_floating_point&lt;T1&gt;::value ||
     boost::is_floating_point&lt;T2&gt;::value)
  {
    return std::ceil(lhs / rhs);
  }
  else if(lhs % rhs)
  {
    return lhs / rhs + 1;
  }

  return lhs / rhs;
}
</code></pre>
<p>Oder sowas in der Richtung. Allerdings könnte man das wesentlich einfacher machen, wenn du die Typen ein wenig mehr einschränken könntest, was die sein können.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1675794</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1675794</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 07 Mar 2009 17:56:54 GMT</pubDate></item><item><title><![CDATA[Reply to std::ceil + divide + templates on Sat, 07 Mar 2009 18:49:53 GMT]]></title><description><![CDATA[<p>&quot;Wieso können es verschiedene Typen sein&quot;<br />
Weil das eine die Kapazität eines Lagers ist - die also auch negativ sein kann (er hat Waren schon verkauft, aber noch nicht liefern können)<br />
Die andere ist die eines Transporters/... - hab ich zwar lang überlegt, ob ich die gleiche nehme, aber fande ich aus vielerlei Gründen nicht gerade gut - deshalb hab ich mich dann auch dagegen entschieden...</p>
<p>&quot;Typen einschränken&quot;<br />
Weiß ich selbst noch nicht so genau - und ich wollte es auch allgemein gültig machen - genauer als oben geht es nicht (atm sind eben beides size_t weil es um abzählare waren geht - aber was, wenn ich iwann mal auf die Idee komme, dass ich irgend ne Maßeinheit haben will -&gt; ich brauche float. Was, wenn ich mehr habe, als 2^32? Ich nehm __int64 - und danach? ^^</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Bei Integer Typen wird deine Funktion wohl kaum das machen, was du willst. Für a / b, wenn a und b ein Integertyp sind, dann wird das Ergebnis abgeschnitten, bevor es an die Funktion geht</p>
</blockquote>
<p>Das hab ich doch gesagt:</p>
<p>unskilled schrieb:</p>
<blockquote>
<p>Kein Problem, solange a oder b floats sind [...]</p>
</blockquote>
<p>und deshalb dann die Lösung mit<br />
<code>return (a+b-1) / b;</code> gepostet - aber diese mit der Frage versehen, ob sie denn wirklich allgemein gültig sei<br />
oder ihr es anders machen würdet ^^</p>
<p>Deine Lösung sieht aber fast hübscher aus ^^</p>
<p>bb</p>
<p>edit: boar - und vor allem warnt der compiler ja jz schon wieder rum (constant expression - da muss man sich wieder drum kümmern, dass man die warning deaktiviert ^^)</p>
<p>(a+1+1/b)/b gilt btw für alle b &gt;= 1 ^^</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1675797</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1675797</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Sat, 07 Mar 2009 18:49:53 GMT</pubDate></item><item><title><![CDATA[Reply to std::ceil + divide + templates on Sat, 07 Mar 2009 18:51:56 GMT]]></title><description><![CDATA[<p>unskilled schrieb:</p>
<blockquote>
<p><code>return (a+b-1) / b;</code> gepostet - aber diese mit der Frage versehen, ob sie denn wirklich allgemein gültig sei<br />
oder ihr es anders machen würdet ^^</p>
</blockquote>
<p>Solange a und b Intergertypen sind und beide positiv, was du ja auch vorgegeben hast, dann glaube ich schon. Diese Lösung dürfte womöglich auch weniger Taktzyklen benötigen als meine. Allerdings schränkst du dich ein, was das Maximum betrifft, wegen dem <code>a + b</code> .</p>
<p>Ansonsten gebe ich dir nur den Rat, dass du es aktuell so löst, wie die Typen auch vorhanden sind. Wenn du später mal die Typen veränderst, passt du auch diese Rechnung an. Sehr wahrscheinlich wird dann sowieso eine Warnung geworfen werden, weil sich die Typen verändert haben. Du könntest dich aber auch mit einem <code>static_assert</code> absichern, damit du es ganz sicher nicht vergisst <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="😉"
    /></p>
<p>Ich bin eigentlich der Meinung, dass dafür Templates zu verwenden, der falsche Weg ist.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1675818</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1675818</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Sat, 07 Mar 2009 18:51:56 GMT</pubDate></item><item><title><![CDATA[Reply to std::ceil + divide + templates on Sat, 07 Mar 2009 19:10:44 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Solange a und b Intergertypen sind und beide positiv, was du ja auch vorgegeben hast, dann glaube ich schon. Diese Lösung dürfte womöglich auch weniger Taktzyklen benötigen als meine. Allerdings schränkst du dich ein, was das Maximum betrifft, wegen dem <code>a + b</code> .</p>
</blockquote>
<p>Ne - ich hatte nicht gesagt, dass es Integer seien ^^ Und es geht nicht für a&lt;1 oder b&lt;1 <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":-/"
      alt="😕"
    /><br />
Wegen der Taktzyklen: Denke ich auch, aber da gibts - wie immer - andere Stellen, wo sehr viel mehr Rechenzeit (mit Sicherheit auch iwo unnötig) verbraten wird...</p>
<p>Dravere schrieb:</p>
<blockquote>
<p>Ich bin eigentlich der Meinung, dass dafür Templates zu verwenden, der falsche Weg ist.</p>
</blockquote>
<p>Ich sehe eigtl genau hier den Einsatz von templates - aber diese Rechnung passt eben nicht so toll da rein - in die ganzen allgemein gültigen Funktionen -.-</p>
<p>Habs jz so gelöst, wie du vorgeschlagen hattest:</p>
<pre><code class="language-cpp">static bool CapacityIsFloatingPoint()
{
	return (boost::is_floating_point&lt;Tcapacity&gt;::value || boost::is_floating_point&lt;Tcapacity_transport&gt;::value);
}

TSpokeContainer::size_type GetNeededTransports(Tcapacity have, Tcapacity need, Tcapacity_transport transport_capacity)
{
	Tcapacity numerator = have - need;
	Tcapacity_transport &amp;denominator = transport_capacity;

	//das sollte so und so immer gegeben sein...
	assert (! (numerator &gt; 0) ^ (denominator &gt; 0) ); //und -3 / -2 würde vom mathematischen her auch gehen - deshalb nen xor und kein or...
	assert ( denominator != 0 );

	if(CapacityIsFloatingPoint())
		return static_cast &lt;TSpokeContainer::size_type&gt; ( std::ceil (static_cast &lt;float&gt; (numerator) / denominator) );

	if(numerator % denominator)
		return numerator / denominator + 1;

	return numerator / denominator;
}
</code></pre>
<p>Sieht zwar echt nich so hübsch aus, wie es davor aussah (und vor allem musste es jz eben wirklich in ne extra fkt), aber es geht wenigsten immer - Danke <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>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1675827</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1675827</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Sat, 07 Mar 2009 19:10:44 GMT</pubDate></item></channel></rss>