Note that there are some explanatory texts on larger screens.

plurals
  1. POMantissa Normalization of C# double
    primarykey
    data
    text
    <p>EDIT: Got it to work now, while normalizing the mantiss it is important to first set the implicit bit, when decoding the implicit bit then does not have to be added. I left the marked answer as correct, as the information there really helped.</p> <p>I'm currently implementing an encoding (Distinguished encoding rules) and have a slight problem encoding double values.</p> <p>So, I can get out the sign, exponent and mantissa from a double in c# by using:</p> <pre><code> // get parts double value = 10.0; long bits = BitConverter.DoubleToInt64Bits(value); // Note that the shift is sign-extended, hence the test against -1 not 1 bool negative = (bits &lt; 0); int exponent = (int)((bits &gt;&gt; 52) &amp; 0x7ffL); long mantissa = bits &amp; 0xfffffffffffffL; </code></pre> <p>(using code from <a href="https://stackoverflow.com/questions/389993/extracting-mantissa-and-exponent-from-double-in-c-sharp">here</a>). These values can be encoded and a simple reversal of the process will get me back the original double.</p> <p>However, the DER encoding rules specify that the mantissa should be normalized:</p> <blockquote> <p>In the Canonical Encoding Rules and the Distinguished Encoding Rules normalization is specified and the mantissa (unless it is 0) needs to be repeatedly shifted until the least significant bit is a 1.</p> </blockquote> <p>(see <a href="http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf" rel="nofollow noreferrer">here in section 8.5.6.5</a>).</p> <p>Doing this by hand using:</p> <pre><code> while ((mantissa &amp; 1) == 0) { mantissa &gt;&gt;= 1; exponent++; } </code></pre> <p>will not work, and gives me strange values. (Even when using the whole function Jon Skeet posted in the aforementioned link).</p> <p>I seem to be missing something here, it would be easiest if I first could normalize the mantiassa of the double and the get the "bits". However, I also can't really see why the normalization by hand won't work correctly.</p> <p>Thanks for any help,</p> <p>Danny</p> <p>EDIT: Actual working problem showing my issue with mantiss normalization:</p> <pre><code> static void Main(string[] args) { Console.WriteLine(CalculateDouble(GetBits(55.5, false))); Console.WriteLine(CalculateDouble(GetBits(55.5, true))); Console.ReadLine(); } private static double CalculateDouble(Tuple&lt;bool, int, long&gt; bits) { double result = 0; bool isNegative = bits.Item1; int exponent = bits.Item2; long significand = bits.Item3; if (exponent == 2047 &amp;&amp; significand != 0) { // special case } else if (exponent == 2047 &amp;&amp; significand == 0) { result = isNegative ? double.NegativeInfinity : double.PositiveInfinity; } else if (exponent == 0) { // special case, subnormal numbers } else { /* old code, wont work double actualSignificand = significand*Math.Pow(2, -52) + 1; */ double actualSignificand = significand*Math.Pow(2, -52); int actualExponent = exponent - 1023; if (isNegative) { result = actualSignificand*Math.Pow(2, actualExponent); } else { result = -actualSignificand*Math.Pow(2, actualExponent);**strong text** } } return result; } private static Tuple&lt;bool, int, long&gt; GetBits(double d, bool normalizeSignificand) { // Translate the double into sign, exponent and mantissa. long bits = BitConverter.DoubleToInt64Bits(d); // Note that the shift is sign-extended, hence the test against -1 not 1 bool negative = (bits &lt; 0); int exponent = (int)((bits &gt;&gt; 52) &amp; 0x7ffL); long significand = bits &amp; 0xfffffffffffffL; if (significand == 0) { return Tuple.Create&lt;bool, int, long&gt;(false, 0, 0); } // fix: add implicit bit before normalization if (exponent != 0) { significand = significand | (1L &lt;&lt; 52); } if (normalizeSignificand) { //* Normalize */ while ((significand &amp; 1) == 0) { /* i.e., Mantissa is even */ significand &gt;&gt;= 1; exponent++; } } return Tuple.Create(negative, exponent, significand); } Output: 55.5 2.25179981368527E+15 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload