Могу ли я контролировать количество цифр, отображаемых в окнах отладчика для переменных типа float и double?

В Visual Studio 2012 я ищу способ настроить отображение по умолчанию типов с плавающей запятой в окнах Autos, Locals и Watch. Я знаком с утилитой Native Visualizer (Natvis), но не вижу каких-либо средств форматирования отладчика для этого. Кроме того, я не знаю каких-либо способов переопределить отображение по умолчанию любых примитивных типов (кроме включения hex).

Цель состоит в том, чтобы создать отображаемые строки с меньшим количеством цифр, развернутых для типов, соответствующих точкам, геометрическим векторам и т. Д., Но при этом при раскрытии типов все еще отображается вся точность. Так, например, я мог бы иметь переменную отображения типа точки как (0.000, 1.234, 2.429) вместо m_x = 0.00000000, m_y = 1.234245213... в средней колонке окна Autos.

Я просмотрел спецификаторы формата на этой странице, но не вижу способа контролировать точность с плавающей точкой.

7 ответов

Решение

К сожалению, на самом деле нет никакого способа сделать этот мелкозернистый уровень изменений в отладке C++. На управляемом языке это было бы возможно в некоторых ограниченных сценариях (когда примитивы были полями объектов и отмечены специальными [DebuggerDisplay] атрибуты). Для C++ этот тип настройки просто не существует.

Хотя это не поддерживается в их документации, мы использовали следующее определение для сокращения чисел (в VS 2015):

  <Type Name="MyVec3d">
    <DisplayString>{vectorX,g}, {vectorY,g}, {vectorZ,g}</DisplayString>
  </Type>

Примитивные типы в настоящее время не могут быть NatVizzed. Однако, если конкретные примитивы, которые вы хотите просмотреть, являются членами другого типа, который вы можете просматривать, вы можете применить форматирование к этому типу, например:

<!-- displays the double value as 0.000 -->
<Type Name="DoubleHolder">
  <DisplayString>{(int)myDouble}.{(int)(myDouble*1000) % 1000}</DisplayString>
</Type>

Основываясь на ответе Overlord Zurg, отобразите значениеm_x с тремя цифрами следующим образом:

<Type Name="Point">
  <DisplayString>
    {(int)m_x}.{(int)(10*m_x) % 10}{(int)(100*m_x) % 10}{(int)(1000*m_x) % 10}
  </DisplayString>
</Type>

Чтобы учесть также отрицательные числа:

<Type Name="Point">
  <DisplayString>
    {(int)m_x}.{(int)((m_x&lt;0?-1:1)*10*m_x) % 10}{(int)((m_x&lt;0?-1:1)*100*m_x) % 10}{(int)((m_x&lt;0?-1:1)*1000*m_x) % 10}
  </DisplayString>
</Type>

Вы не имеете большого контроля над этим. Однако мы смогли получить что-то немного лучше, чем представление по умолчанию, приведя наши двойные числа к плавающим для предварительного просмотра:

<DisplayString>{{x={(float)x} y={(float)y}}}</DisplayString>

Мы оставили их как двойники в развернутой версии, чтобы вы могли видеть истинные значения. Этого было достаточно для нас, чтобы упаковать четыре или пять значений по горизонтали вместо обычных трех. Это по-прежнему имеет ряд недостатков: последние несколько цифр на поплавке будут мусором и могут заставить вас думать, что у вас есть ошибки точности, хотя на самом деле это не так. Однако до тех пор, пока Microsoft не добавит правильные спецификаторы форматирования для числового вывода, это, пожалуй, лучшее, что мы можем сделать.

Между прочим, вы можете, вероятно, получить аналогичную "прерванную точность", приведя ваши числа с плавающей точкой к целым, если значения обычно достаточно велики.

Единственный способ сделать это, о котором я знаю, - это написать собственную DLL визуализатора. Посмотрите этот ответ на вопрос "Как написать собственную DLL-библиотеку визуализатора для отладчика Visual Studio 2012?",

Я успешно использовал это и источники, связанные в этом ответе, для написания пользовательских визуализаторов, которые отображают члены с плавающей запятой различных типов с требуемой точностью.

Вы можете вызывать функции, и это прекрасно работает. nq означает отсутствие кавычек, /questions/23415508/vliyaet-li-direktiva-debuggerdisplay-nq-tolko-na-stroki/23415525#23415525

      [DebuggerDisplay("ZA #{id} {display_x.ToString(\"F2\"),nq}")]
public class Zaa 
{
    public int id = 2;
    public double display_x = 5.2354235423;
}
Другие вопросы по тегам