Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Visual Studio display a System.Double during debugging?

Try debugging the following simple program, and mouse over x in each step (or "Add Watch" for x or whatever).

using System;
using System.Globalization;

static class Program
{
  static double x;

  static void Main()
  {
    x = 2d;

    // now debugger shows "2.0", as if it has used
    // x.ToString("F1", CultureInfo.InvariantCulture)

    x = 8.0 / 7.0;

    // now debugger shows "1.1428571428571428", as if it had used
    // x.ToString("R", CultureInfo.InvariantCulture)
    // Note that 17 significant figures are shown, not the usual 15.

    x = -1e-200 / 1e200;

    // now debugger shows "0.0"; there is no indication that this is really negative zero
    //

    Console.WriteLine(1.0 / x); // this is negative infinity
  }
}

So, apparently VS has its own way to display a System.Double. Which method does it call for this purpose? Is there a way I can get the very same string representation programmatically?

(Tried this out with Visual Studio 2010 Professional.)

like image 485
Jeppe Stig Nielsen Avatar asked Apr 20 '12 18:04

Jeppe Stig Nielsen


2 Answers

At their core both the C# and VB.Net EE's use the _ecvt_s function for formatting a double into a string.

  • http://msdn.microsoft.com/en-us/library/ehz2dset(v=vs.80).aspx

Both do a little bit of cleanup on the resulting string to make the display more C# and VB like and handle some corner cases a bit nicer. Either the _ecvt_s function or the cleanup code could be responsible for the differences you see. Hard to tell at a glance

Some may ask why we would go through all of this trouble instead of saying just calling ToString on the value and displaying that. There are a couple of reasons we don't do this.

The first is simply that function evaluation, even ToString, is the single most expensive action the EE can undertake. Profiles of common real scenarios show that over 98% of our time was spent doing function evaluation. Any time we can avoid a func eval we do because of the performance implications.

The second reason is simply that function evaluation isn't always available. There are a number of cases where func eval is unavailable yet people still expect to see a display for primitive types like double, int, etc ... Taking them away would essentially kill the debugging experience. Hence we need to solve this problem without ToString support.

like image 140
JaredPar Avatar answered Sep 26 '22 00:09

JaredPar


I will accept JaredPar's answer since it describes how things work inside the debugger.

But because the answer does not help to get the same string, here is some code that often (always?) gives the same string:

static string ToDebugString(this double d)
{
  if (Double.IsNaN(d) || Double.IsInfinity(d))
    return d.ToString(CultureInfo.InvariantCulture);

  string s = d.ToString("R", CultureInfo.InvariantCulture);
  if (!s.Contains("."))
    s += ".0";
  return s;
}

Please feel free to improve this answer.

like image 28
Jeppe Stig Nielsen Avatar answered Sep 25 '22 00:09

Jeppe Stig Nielsen