<?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[float um kleinsten Schritt ändern.]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein dummes Rundungs-Problem:</p>
<pre><code class="language-cpp">float x=1234.5678;
float y=1.2345678;
</code></pre>
<p>Ich möchte einen bestehenden Float-Wert um den kleinsten Wert, der möglich ist,<br />
erhöhen bzw. vermindern. Die normale Addition ist unbrauchbar, da der Wert, der<br />
sich Addieren/Subtrahieren läßt, bei x und y unterschiedlich ist. Ich nehme an,<br />
daß ich da direkt die Mantisse mit Bit-Operationen behandeln muß. Wie geht das<br />
portabel?</p>
<p>Danke, lg</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/286371/float-um-kleinsten-schritt-ändern</link><generator>RSS for Node</generator><lastBuildDate>Thu, 20 Aug 2026 22:26:27 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/286371.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 08 May 2011 19:27:01 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Sun, 08 May 2011 19:27:01 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe ein dummes Rundungs-Problem:</p>
<pre><code class="language-cpp">float x=1234.5678;
float y=1.2345678;
</code></pre>
<p>Ich möchte einen bestehenden Float-Wert um den kleinsten Wert, der möglich ist,<br />
erhöhen bzw. vermindern. Die normale Addition ist unbrauchbar, da der Wert, der<br />
sich Addieren/Subtrahieren läßt, bei x und y unterschiedlich ist. Ich nehme an,<br />
daß ich da direkt die Mantisse mit Bit-Operationen behandeln muß. Wie geht das<br />
portabel?</p>
<p>Danke, lg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2060606</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2060606</guid><dc:creator><![CDATA[round]]></dc:creator><pubDate>Sun, 08 May 2011 19:27:01 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Sun, 08 May 2011 19:40:15 GMT]]></title><description><![CDATA[<p>round schrieb:</p>
<blockquote>
<p>Wie geht das portabel?</p>
</blockquote>
<p>Garnicht. Entweder Addition mit Epsilon oder tja...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2060621</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2060621</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Sun, 08 May 2011 19:40:15 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Mon, 09 May 2011 07:14:51 GMT]]></title><description><![CDATA[<p>round schrieb:</p>
<blockquote>
<p>Ich möchte einen bestehenden Float-Wert um den kleinsten Wert, der möglich ist,<br />
erhöhen bzw. vermindern.</p>
</blockquote>
<p>Wozu eigentlich?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2060710</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2060710</guid><dc:creator><![CDATA[why]]></dc:creator><pubDate>Mon, 09 May 2011 07:14:51 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Mon, 09 May 2011 20:49:30 GMT]]></title><description><![CDATA[<p>der ieee standart sagt das die reihenfolge im binärformat linear ist, also in int umwandeln +1 und wieder zurück.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061033</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061033</guid><dc:creator><![CDATA[ololo]]></dc:creator><pubDate>Mon, 09 May 2011 20:49:30 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Mon, 09 May 2011 21:23:36 GMT]]></title><description><![CDATA[<p>why schrieb:</p>
<blockquote>
<p>round schrieb:</p>
<blockquote>
<p>Ich möchte einen bestehenden Float-Wert um den kleinsten Wert, der möglich ist,<br />
erhöhen bzw. vermindern.</p>
</blockquote>
<p>Wozu eigentlich?</p>
</blockquote>
<p>Ein CAD-Tool. Die Koordinaten von Punkten liegen in hochgenauen rationalen<br />
Zahlen vor. Gesucht ist eine Repräsentation mit 32bit-Float. Die verändert<br />
die Geometrie und ist nicht immer zulässig. Eine Heuristik, die meistens<br />
funktionieren wird ist, daß man die nähesten Koordinaten aller Richtungen<br />
ausprobiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061050</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061050</guid><dc:creator><![CDATA[round]]></dc:creator><pubDate>Mon, 09 May 2011 21:23:36 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Mon, 09 May 2011 21:49:04 GMT]]></title><description><![CDATA[<p>Deine rationalen Zahlen in float umwandeln wirst du wohl durch eine einfache Division, das gibt dir dann aber doch schon den jeweils nähesten float für jede Koordinate, oder!? Ansonsten 1 zur Mantisse addieren oder evtl. mit den Rounding Modes der FPU spielen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061054</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061054</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Mon, 09 May 2011 21:49:04 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Mon, 09 May 2011 21:53:43 GMT]]></title><description><![CDATA[<p>Es gibt im C99-Standard eine Funktion nextafter, die das macht:</p>
<pre><code class="language-cpp">#include &lt;stdio.h&gt;
#include &lt;math.h&gt;

int main() {
  double x = 1.234;

  printf(&quot;%.16lf, %.16lf\n&quot;, nextafter(x, 0.0), nextafter(x, 2.0));

  return 0;
}
</code></pre>
<pre><code>$ gcc test.c &amp;&amp; ./a.out 
1.2339999999999998, 1.2340000000000002
</code></pre>
<p>In C++98 ist diese leider nicht enthalten (weiß jemand, ob sie in C++11 vorgesehen ist?), aber eine Menge Compiler dürften sie inzwischen können. Mit MSVC bist du allerdings wahrscheinlich aufgeschmissen.</p>
<p>Ansonsten könntest du über std::numeric_limits unter der Annahme, dass es sich um IEE754-Fließkommazahlen handelt, den Exponenten ausklamüsern und dein Epsilon selbst zusammensetzen, aber das ist alles andere als trivial. Behalte im Hinterkopf, dass IEE-754 subnormale Darstellungen erlaubt und das Epsilon je nach Richtung unterschiedlich groß sein kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061060</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061060</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 09 May 2011 21:53:43 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Mon, 09 May 2011 22:27:17 GMT]]></title><description><![CDATA[<p>Nachtrag: Eine Näherung (d.h. ohne die Bruchstellen) <strong>ausschließlich für 32-Bit-IEEE-754-floats</strong>:</p>
<pre><code class="language-cpp">int intlog2(float f) {
  union {
    int i;
    float f;
  } v;

  int x;
  int c;

  v.f =   f;
  x   = v.i;

  c = x &gt;&gt; 23;

  if(c) {
    c -= 127;
  } else {
    int t;
    static const char LogTable256[256] =  {
#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
      -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
      LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
      LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
#undef LT
    };

    if (t = x &gt;&gt; 16) {
      c = LogTable256[t] - 133;
    } else {
      c = (t = x &gt;&gt; 8) ? LogTable256[t] - 141 : LogTable256[x] - 149;
    }
  }

  return c;
}

float epsilon(float x) {
  return pow(2, intlog2(x) - 23);
}
</code></pre>
<p>intlog2 stammt <a href="http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogFloat" rel="nofollow">hierher</a>.</p>
<p>Soweit ich das überblicke, verlässt sich der Code darauf, dass int 32 Bit breit ist (wie auch der float). Beim float kann man sich einigermaßen darauf verlassen - der Standard empfiehlt, float auf den IEEE-754-single zu mappen, und wenn IEE-754 nicht eingehalten wird, funktioniert das Ganze eh nicht - aber bei int wird das wahrscheinlich irgendwann nicht mehr der Fall sein. Ggf. solltest du also int32_t, __int32 o.ä. benutzen (bzw. auf boost/cstdint.hpp zurückgreifen).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061064</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061064</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 09 May 2011 22:27:17 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Tue, 10 May 2011 06:16:50 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>Deine rationalen Zahlen in float umwandeln wirst du wohl durch eine einfache Division, das gibt dir dann aber doch schon den jeweils nähesten float für jede Koordinate, oder!? Ansonsten 1 zur Mantisse addieren oder evtl. mit den Rounding Modes der FPU spielen.</p>
</blockquote>
<p>Ja, das gibt den nächsten Float. Der könnte aber die Geometrie in ungültiger<br />
Weise verändern, so daß ich von dort aus in alle Achsen-Richtungen up/down<br />
runden und so andere Kandidaten finden will.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061092</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061092</guid><dc:creator><![CDATA[round]]></dc:creator><pubDate>Tue, 10 May 2011 06:16:50 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Tue, 10 May 2011 08:33:31 GMT]]></title><description><![CDATA[<p>Ich habe es per Schleife gelöst.</p>
<pre><code class="language-cpp">void nextValsFloat(float x,float&amp; xdn,float&amp; xup)
{
	float addVal(1.0);
	do
	{
		addVal/=2.0;
	} while(x+addVal!=x);
	addVal*=2.0;
	cout&lt;&lt;&quot;addVal to be used: &quot;&lt;&lt;addVal&lt;&lt;endl;
	xdn=x-addVal;
	xup=x+addVal;

}
</code></pre>
<p>addVal darf maximal 1 sein, und eigentlich müßte man für xdn und xup den addVal<br />
separat ausrechnen. Aber für das gegebene Setting ist das okay.</p>
<p>Danke für die Hinweise!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061139</guid><dc:creator><![CDATA[round]]></dc:creator><pubDate>Tue, 10 May 2011 08:33:31 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Tue, 10 May 2011 09:10:17 GMT]]></title><description><![CDATA[<p>round schrieb:</p>
<blockquote>
<p>Der könnte aber die Geometrie in ungültiger Weise verändern, so daß ich von dort aus in alle Achsen-Richtungen up/down runden und so andere Kandidaten finden will.</p>
</blockquote>
<p>Dein eigentliches Problem hat also gar nichts mit</p>
<blockquote>
<p>float um kleinsten Schritt ändern</p>
</blockquote>
<p>zutun.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061155</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061155</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Tue, 10 May 2011 09:10:17 GMT</pubDate></item><item><title><![CDATA[Reply to float um kleinsten Schritt ändern. on Tue, 10 May 2011 09:23:30 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>round schrieb:</p>
<blockquote>
<p>Der könnte aber die Geometrie in ungültiger Weise verändern, so daß ich von dort aus in alle Achsen-Richtungen up/down runden und so andere Kandidaten finden will.</p>
</blockquote>
<p>Dein eigentliches Problem hat also gar nichts mit</p>
<blockquote>
<p>float um kleinsten Schritt ändern</p>
</blockquote>
<p>zutun.</p>
</blockquote>
<p>Ein hochgenauer 3D-Punkt soll durch einen Punkt mit Floatingpoint-Koordinaten<br />
ersetzt werden. Da die automatische Rundung nicht zwangsläufig zu einem guten<br />
Punkt 'proxy' führt, sollen weitere Punkte innerhalb einer kleinen Sphere rund<br />
um proxy erzeugt werden. Daher die Notwendigkeit einer möglichst geringen<br />
Änderung von Float-Werten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2061160</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2061160</guid><dc:creator><![CDATA[round]]></dc:creator><pubDate>Tue, 10 May 2011 09:23:30 GMT</pubDate></item></channel></rss>