Daniel Albuschat
Daniel Albuschat

Reputation: 816

Visualize custom floating point class in debugger

I already did some fiddling in autoexp.dat to ease the inspection of custom string and other simple classes in the Visual Studio debugger (using vs2005). I'd really love to directly see the value (or approximation) of our custom floating point class. The internal representation is a quad-integer (int mantissa[4], 128bit on x86) that will be divided by 10 to the power of our exponent. So it basically looks like this:

class FloatingPoint
{
   private:
      char exponent;
      int mantissa[4]
};

The following statement would convert it to double, given fp is an object of type FloatingPoint:

(mantissa[0] + 
   * ((double)mantissa[1] * 32 * 2) 
   * ((double)mantissa[2] * 64 * 2) 
   * ((double)mantissa[3] * 96 * 2))
   /  std::pow(10, fp.exponent)

Is it possible to somehow get the Visual Studio debugger show objects of type FloatingPoint using this calculation? The call to pow is an extra problem, because this function has no external linking and can not be called by the debugger... maybe there's a way around this?

Upvotes: 3

Views: 375

Answers (2)

MSalters
MSalters

Reputation: 179917

Another approach that may work is

const char* FloatingPoint::ToString () const
{
  static char buf[64];
  double d = (mantissa[0] + 
   * ((double)mantissa[1] * 32 * 2) 
   * ((double)mantissa[2] * 64 * 2) 
   * ((double)mantissa[3] * 96 * 2))
   /  std::pow(10, fp.exponent);
  sprintf(buf, "%f", d);
  return buf;
}

which would allow Floatingpoint =<ToString()> in the [AutoExpand] section.

Upvotes: 2

MSalters
MSalters

Reputation: 179917

Since the range of possible exponents is so small, add a (debug-only) lookup table double power10[256];. The debugger will happily use that. Only downside: debugging constructors of global objects may happen before the array is initialized, in which case those values will still be 0. You will need to call the initializer function yourself, from the Immediate Window, if this happens.

On a slightly-related note, you'll want to choose either signed char or unsigned char for the exponent. (Probably signed, else there's no point to float). Plain char has an implementation-defined sign, and here that sign is quite relevant.

Quick attempt (not tested) :

FloatingPoint {
  preview (
    #([($c.mantissa[0]  + $c.mantissa[1] * 64.0 + $c.mantissa[2] * 128.0 + $c.mantissa[3] * 192.0) / power10[$c.exponent], f])
  )
  stringview (
    #([($c.mantissa[0]  + $c.mantissa[1] * 64.0 + $c.mantissa[2] * 128.0 + $c.mantissa[3] * 192.0) / power10[$c.exponent], f])
  )
  children([$c,!])
}

Upvotes: 2

Related Questions