<?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[Long Double zu unsigned integer typ]]></title><description><![CDATA[<p>Hallo, ich möchte aus einer Long double variable einen unsigned integer machen:</p>
<pre><code class="language-cpp">long double EineZahl;
if(EineZahl&lt;1.0)
   return 0;
else
   return std::bitset&lt;256&gt; tmp(UmwandlungZuGroßemInteger(EineZahl));
</code></pre>
<p>Im Prinzip muss ich ja dafür die Mantisse auslesen und diese dann so oft shiften, wie es der Exponent vorgibt. zB:</p>
<pre><code class="language-cpp">std::bitset&lt;256&gt; tmp = MantisseVonLongDouble;
tmp &lt;&lt;= ExponentVonLongDouble; //oder rechtsshift halt
</code></pre>
<p>Die Mantisse auszulesen ist ja nicht schwer (es ist vorgegeben, dass little Endian benutzt wird)</p>
<pre><code class="language-cpp">long double EineZahl;
unsigned char arr[ sizeof(long double) ];
std::memcpy(arr, &amp;EineZahl, sizeof(long double));

std::bitset&lt;256&gt; tmp;
//fülle das bitset mit der mantisse von der long double variable
for(unsigned int i = 0; i != sizeof(long double); ++i)
    for(unsigned int j = 0; j != CHAR_BIT; ++j)
    {
       if( CHAR_BIT*i+j == LDBL_MANT_DIG )
            return tmp;
       if( arr[i] &amp; (1&lt;&lt;j) )
            tmp[ i * CHAR_BIT + j ] = true;
    }
</code></pre>
<p>Aber wie ist der Exponent aufgebaut? Im Prinzip ist der Exponent ja ( CHAR_BIT * sizeof(long double) - LDBL_MANT_DIG - 1 ) bits lang. Aber wie stellt der positive/negative werte dar? das hab ich bisher nicht verstanden.<br />
Hilft es zu wissen, ob sich an den iec Standard gehalten wird? (numeric_limits&lt;long double&gt;::is_iec559)</p>
<p>Schon mal vielen Dank an alle, die Vorschläge machen <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/topic/268265/long-double-zu-unsigned-integer-typ</link><generator>RSS for Node</generator><lastBuildDate>Tue, 01 Sep 2026 21:04:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/268265.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 06 Jun 2010 21:46:22 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Sun, 06 Jun 2010 21:46:22 GMT]]></title><description><![CDATA[<p>Hallo, ich möchte aus einer Long double variable einen unsigned integer machen:</p>
<pre><code class="language-cpp">long double EineZahl;
if(EineZahl&lt;1.0)
   return 0;
else
   return std::bitset&lt;256&gt; tmp(UmwandlungZuGroßemInteger(EineZahl));
</code></pre>
<p>Im Prinzip muss ich ja dafür die Mantisse auslesen und diese dann so oft shiften, wie es der Exponent vorgibt. zB:</p>
<pre><code class="language-cpp">std::bitset&lt;256&gt; tmp = MantisseVonLongDouble;
tmp &lt;&lt;= ExponentVonLongDouble; //oder rechtsshift halt
</code></pre>
<p>Die Mantisse auszulesen ist ja nicht schwer (es ist vorgegeben, dass little Endian benutzt wird)</p>
<pre><code class="language-cpp">long double EineZahl;
unsigned char arr[ sizeof(long double) ];
std::memcpy(arr, &amp;EineZahl, sizeof(long double));

std::bitset&lt;256&gt; tmp;
//fülle das bitset mit der mantisse von der long double variable
for(unsigned int i = 0; i != sizeof(long double); ++i)
    for(unsigned int j = 0; j != CHAR_BIT; ++j)
    {
       if( CHAR_BIT*i+j == LDBL_MANT_DIG )
            return tmp;
       if( arr[i] &amp; (1&lt;&lt;j) )
            tmp[ i * CHAR_BIT + j ] = true;
    }
</code></pre>
<p>Aber wie ist der Exponent aufgebaut? Im Prinzip ist der Exponent ja ( CHAR_BIT * sizeof(long double) - LDBL_MANT_DIG - 1 ) bits lang. Aber wie stellt der positive/negative werte dar? das hab ich bisher nicht verstanden.<br />
Hilft es zu wissen, ob sich an den iec Standard gehalten wird? (numeric_limits&lt;long double&gt;::is_iec559)</p>
<p>Schon mal vielen Dank an alle, die Vorschläge machen <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/1908029</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908029</guid><dc:creator><![CDATA[Umwandelnung]]></dc:creator><pubDate>Sun, 06 Jun 2010 21:46:22 GMT</pubDate></item><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Mon, 07 Jun 2010 01:34:25 GMT]]></title><description><![CDATA[<p>So, ich hab mich jetzt mal weiter damit beschäftigt und gelesen, dass es beim Exponent einen &quot;bias&quot; gibt und versucht das zu implementieren. Hier mein Programm (sieht ziemlich lang aus, ist es aber nicht <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="😉"
    /> ). Anmerkung: print gibt ein bitset als string aus und schneidet führenden Nullen ab.</p>
<pre><code class="language-cpp">template&lt;typename T, std::size_t N&gt; //T = float, N = 1024 damit es nicht zu überläufen im bitset kommen kann
std::bitset&lt;N&gt; cast(T EineZahl)
{
	//----------------------------------------------------------------------------------------------------------
	// Zahlen kleiner 1 ausschließen
	//----------------------------------------------------------------------------------------------------------
    if(EineZahl &lt; (T)1.0)
	{
		std::cerr&lt;&lt;&quot;ERROR: Value too small!&quot;&lt;&lt;std::endl;
        return std::bitset&lt;N&gt;();
	}

	//----------------------------------------------------------------------------------------------------------
	// Eigenschaften von T ausgeben
	//----------------------------------------------------------------------------------------------------------
	const unsigned int exp_size = sizeof(T) * CHAR_BIT - (std::numeric_limits&lt;T&gt;::digits+1) ;
	const unsigned long int bias = (1&lt;&lt;(exp_size-1))-1;
	std::cout&lt;&lt;&quot;Bits in T   : &quot;&lt;&lt;sizeof(T)*CHAR_BIT&lt;&lt;std::endl;
	std::cout&lt;&lt;&quot;Bits in Mant: &quot;&lt;&lt;std::numeric_limits&lt;T&gt;::digits&lt;&lt;std::endl;
	std::cout&lt;&lt;&quot;Bits in Exp : &quot;&lt;&lt;exp_size&lt;&lt;std::endl;
	std::cout&lt;&lt;&quot;Bias        : &quot;&lt;&lt;bias&lt;&lt;std::endl&lt;&lt;std::endl;

	//----------------------------------------------------------------------------------------------------------
	// Long Double ins Bitset übetragen
	//----------------------------------------------------------------------------------------------------------
	unsigned char arr[ sizeof(T) ];
    std::memcpy(arr, &amp;EineZahl, sizeof(T));

    std::bitset&lt;N&gt; Zahl;

    for(unsigned int i = 0; i != sizeof(T); ++i)
        for(unsigned int j = 0; j != CHAR_BIT; ++j)
           if( arr[i] &amp; (1&lt;&lt;j) )
                Zahl[ i * CHAR_BIT + j ] = true;

	//----------------------------------------------------------------------------------------------------------
	// Zahl in mantisse kopieren und alle bits nach der Mantisse auf 0 setzen
	//----------------------------------------------------------------------------------------------------------
    std::bitset&lt;N&gt; mantisse = Zahl;
	for(unsigned int i = std::numeric_limits&lt;T&gt;::digits; i != sizeof(T) * CHAR_BIT; ++i)
        mantisse.reset(i);

	//----------------------------------------------------------------------------------------------------------
	// Zahl in exponent kopieren und so oft rechts shiften, dass nur noch der exponent drin steht
	//----------------------------------------------------------------------------------------------------------
    std::bitset&lt;N&gt; exponent = Zahl;
    exponent&gt;&gt;=std::numeric_limits&lt;T&gt;::digits; //sign bit kann ignoriert werden, da es hier immer 0 ist

	//----------------------------------------------------------------------------------------------------------
	// Mantisse und Exponent binär ausgeben
	//----------------------------------------------------------------------------------------------------------
	std::cout&lt;&lt;&quot;Mantisse    : &quot;&lt;&lt;print(mantisse)&lt;&lt;std::endl;
	std::cout&lt;&lt;&quot;Exponent    : &quot;&lt;&lt;print(exponent)&lt;&lt;std::endl;

	//----------------------------------------------------------------------------------------------------------
	// Bitset exponent in unsigned long umwandeln
	//----------------------------------------------------------------------------------------------------------
	unsigned long int exp_val;
    try
    {
        exp_val = exponent.to_ulong();
    }
    catch(...)
    {
		std::cerr&lt;&lt;&quot;ERROR: Cannot convert exponent!&quot;&lt;&lt;std::endl;
        return std::bitset&lt;N&gt;();
    }

	//----------------------------------------------------------------------------------------------------------
	// Exponent vor und nach Verrechnung mit Bias
	//----------------------------------------------------------------------------------------------------------
    std::cout&lt;&lt;&quot;exp (before): &quot;&lt;&lt;exp_val&lt;&lt;std::endl;
	int sign = 1;
	if(bias &gt; exp_val) sign = -1;
    exp_val -= bias;
	exp_val &amp;= ((1&lt;&lt;exp_size)-1) ; //exp_val auf exp_size stellen begrenzen (falls overflow bei subtraktion)
	std::cout&lt;&lt;&quot;exp (after) : &quot;&lt;&lt;exp_val&lt;&lt;std::endl;

	//----------------------------------------------------------------------------------------------------------
	// Verrechnung von Mantisse und Exponent
	//----------------------------------------------------------------------------------------------------------
	if(sign == 1)
        mantisse &lt;&lt;= exp_val;
    else
        mantisse &gt;&gt;= exp_val;

    return mantisse;
}

int main()
{
	const std::size_t N = 1024;
    std::bitset&lt;N&gt; tmp = cast&lt;float, N&gt;(123.0f);

	std::cout&lt;&lt;std::endl;
    try
    {
		std::cout&lt;&lt;&quot;Zahl fertig : &quot;&lt;&lt;print(tmp)&lt;&lt;std::endl;
		std::cout&lt;&lt;&quot;Zahl ulong  : &quot;&lt;&lt;tmp.to_ulong()&lt;&lt;std::endl;
    }
	catch(...)
    {
		std::cout&lt;&lt;&quot;ERRROR: Cannot convert to ulong in main()!&quot;;
    }
}
</code></pre>
<p>Ausgabe (Bei den Bitsets sind alle führenden, das heißt höherwertigen Nullen abgeschnitten. Links steht das höchstwertigste Bit und rechts das Niedrigste. Intern sind die Bits andersrum angeordnet. Bitset[0] enthält das Niedrigste.):</p>
<pre><code>Bits in T   : 32
Bits in Mant: 24
Bits in Exp : 7
Bias        : 63

Mantisse    : 111101100000000000000000
Exponent    : 1000010
exp (before): 66        (bevor bias verrechnet wird)
exp (after) : 3

Zahl fertig : 111101100000000000000000000
Zahl ulong  : 128974848

Erwartetes Ergebnis:
Zahl fertig : 1111011
Zahl ulong  : 123
</code></pre>
<p>4 Sachen wundern mich:</p>
<ul>
<li>Warum sind bei der Mantisse die höher wertigen Bits gesetzt und nicht die niedrigen, so wie im Exponent?</li>
<li>Auf Wikipedia steht, man soll den Bias vom Exponenten abziehen. Wenn ich ihn allerdings addiere, dann ist der Exponent hier nicht 3 sondern 1 (was mir irgendwie plausibler erscheint)</li>
<li>Auf Wikipedia steht, man solle 1 auf die Mantisse addieren. Aber hier ist die Mantisse doch schon meine gesuchte Zahl?!</li>
<li>Warum habe ich hier andere Werte für die Eigenschaften von float, obwohl sich mein Compiler (Microsoft Visual C++ Express) angeblich an den iec559 standard hält? (laut wikipedia hat ein 32bit float nach diesem standard 23 bits mantisse und 8 bits exponent, nicht 24 und 7 wie bei mir)</li>
</ul>
<p>Was mache ich hier also falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1908065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908065</guid><dc:creator><![CDATA[Umwandelnung]]></dc:creator><pubDate>Mon, 07 Jun 2010 01:34:25 GMT</pubDate></item><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Mon, 07 Jun 2010 05:49:53 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">long double foo=1234.5678;
  long unsigned int bar=foo;
</code></pre>
<p>Hab ich jetzt gewonnen?</p>
<p>Übrigens: Der interne Aufbau von doubles ist nicht standardisiert. Wie genau der double aufgebaut ist, steht in der Anleitung deines Compilers. Vermutlich in Form eines Verweises auf den IEEE 754 Standard.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1908090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908090</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 07 Jun 2010 05:49:53 GMT</pubDate></item><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Mon, 07 Jun 2010 10:40:25 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<pre><code class="language-cpp">long double foo=1234.5678;
  long unsigned int bar=foo;
</code></pre>
<p>Hab ich jetzt gewonnen?</p>
</blockquote>
<pre><code class="language-cpp">long double foo = 2e100L;
unsigned int bar = foo; //unfug
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1908237</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908237</guid><dc:creator><![CDATA[Umwandelnung]]></dc:creator><pubDate>Mon, 07 Jun 2010 10:40:25 GMT</pubDate></item><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Mon, 07 Jun 2010 10:54:27 GMT]]></title><description><![CDATA[<p>den unfug kannst du aber auch mit einer million zeilen selbstgefrickeltem code nicht loswerden. was nicht geht, geht nicht. und wenn du rausfinden willst, ob's geht, vergleich den double halt vorher mit std::numeric_limits&lt;zieltyp&gt;::min() und max().</p>
<p>ru,<br />
cirion</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1908245</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908245</guid><dc:creator><![CDATA[cirion]]></dc:creator><pubDate>Mon, 07 Jun 2010 10:54:27 GMT</pubDate></item><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Mon, 07 Jun 2010 10:58:35 GMT]]></title><description><![CDATA[<p>Das ist kein Unfug, denn:</p>
<pre><code class="language-cpp">long double foo = 2e200L;
MeinInteger bar = foo;
</code></pre>
<p>lässt sich verlustfrei darstellen. Dafür muss ich aber Exponent und Mantisse auslesen und mir das selbst zusammen basteln.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1908247</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908247</guid><dc:creator><![CDATA[Umwandelnung]]></dc:creator><pubDate>Mon, 07 Jun 2010 10:58:35 GMT</pubDate></item><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Mon, 07 Jun 2010 11:46:21 GMT]]></title><description><![CDATA[<p>siehe <a href="http://www.cplusplus.com/reference/clibrary/cmath/frexp/" rel="nofollow">std::frexp</a> aus <a href="http://www.cplusplus.com/reference/clibrary/cmath/" rel="nofollow">&lt;cmath&gt;</a></p>
<p>gruß,<br />
kk</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1908288</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908288</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Mon, 07 Jun 2010 11:46:21 GMT</pubDate></item><item><title><![CDATA[Reply to Long Double zu unsigned integer typ on Mon, 07 Jun 2010 22:51:25 GMT]]></title><description><![CDATA[<p>@Umwandelnung:<br />
Alle deine Fragen sollten sich von selbst beantworten wenn du mal weitere 5 oder 10 Minuten erübrigst um dich ein wenig über IEEE 754 schlau zu lesen.<br />
Bei 32 Bit Zahlen nach IEEE 754 ist die führende 1 der 24 Bit langen Mantisse implizit, wird also nicht in den 32 Bit abgespeichert.</p>
<p>Ich schätze mal das wird der Grund sein warum <code>std::numeric_limits&lt;float&gt;::digits</code> 24 liefert, obwohl das verwendete Format (32 Bit Binär-Representation nach IEEE 754 aka. IEC 559) nur 23 Bit der Mantisse abspeichert. 23 Bit + 1 implizites = 24.</p>
<p>Der Rest sind Folgefehler.</p>
<p>Dann stimmt auch auf einmal der Exponent (133 - 127 = 6 = korrekter Exponent für 123, da 123 = 1,..... * 2^6).</p>
<p>Wenn du wirklich direkt Bit-Gefummel betreiben willst, dann würde ich an deiner Stelle eher die diversen Konstanten aus IEEE 754 direkt irgendwo in den Code schreiben. Andere Floating-Point Representationen könnten gänzlich anders aussehen, wodurch dein &quot;generischer&quot; Code sowieso versagen würde. Nebenbei wird es schon kaum möglich sein einen &quot;generischen&quot; Bitfummler Code zu bauen der mit 32 Bit und 64 Bit Floats nach IEEE 754 klarkommt, da die führende 1 in der Mantisse bei 64 Bit Floats nach IEEE 754 nämlich sehr wohl abgespeichert wird (im Gegensatz zu 32 Bit Floats nach IEEE 754). Also zumindest nicht ohne 32/64 Bit Fallunterscheidung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1908681</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1908681</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 07 Jun 2010 22:51:25 GMT</pubDate></item></channel></rss>