Debugger: Add support for two more floating point display formats

1. The `std::hexfloat` representation produced by `std::sstream`.
2. Breaking the number into a normalized value and a integral power of 2,
   as does the `std::frexp()` function.

M_PI looks like "0x1.921fb54442d18p+1" and "0.785398163397 * 2^2"
respectively.

Fixes: QTCREATORBUG-26793
Change-Id: Ib08ea9408f79201434eb75ec328b94ab933259a4
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2022-01-06 18:10:04 +01:00
parent 03d4fdc602
commit 1abe76549e
4 changed files with 51 additions and 1 deletions

View File

@@ -316,7 +316,9 @@ enum DisplayFormat
CharCodeIntegerFormat = 28, // Frontend internal only
CompactFloatFormat = 26, // Frontend internal only
ScientificFloatFormat = 27 // Frontend internal only
ScientificFloatFormat = 27, // Frontend internal only
HexFloatFormat = 29, // Frontend internal only
NormalizedTwoFloatFormat = 30, // Frontend internal only
};

View File

@@ -628,6 +628,19 @@ QString WatchItem::sourceExpression() const
return QString("%1.%2").arg(p->sourceExpression(), name);
}
int WatchItem::guessSize() const
{
if (size != 0)
return size;
if (type == "double")
return 8;
if (type == "float")
return 4;
if (type == "qfloat16")
return 2;
return 0;
}
} // namespace Internal
} // namespace Debugger

View File

@@ -65,6 +65,7 @@ public:
bool isValid() const { return !iname.isEmpty(); }
bool isVTablePointer() const;
int guessSize() const;
void setError(const QString &);
void setValue(const QString &);

View File

@@ -63,6 +63,7 @@
#include <QClipboard>
#include <QDebug>
#include <QFile>
#include <QFloat16>
#include <QItemDelegate>
#include <QJsonArray>
#include <QJsonObject>
@@ -80,7 +81,10 @@
#include <QVBoxLayout>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <sstream>
#include <ctype.h>
using namespace Core;
@@ -770,6 +774,32 @@ static QString formattedValue(const WatchItem *item)
return QString::number(dd, 'g');
}
if (format == HexFloatFormat) {
double dd = item->value.toDouble();
std::ostringstream ss;
ss << std::hexfloat;
switch (item->guessSize()) {
case 2: ss << qfloat16(dd); break;
case 4: ss << float(dd); break;
default: ss << dd; break;
}
return QString::fromStdString(ss.str());
}
if (format == NormalizedTwoFloatFormat) {
double dd = item->value.toDouble();
std::ostringstream ss;
int pow2_exp;
double norm = std::frexp(dd, &pow2_exp);
int numDecimalDigits = 12;
switch (item->guessSize()) {
case 2: numDecimalDigits = 4; break;
case 4: numDecimalDigits = 8; break;
default: break;
}
return QString::number(norm, 'f', numDecimalDigits) + " * 2^" + QString::number(pow2_exp);
}
if (item->type == "va_list")
return item->value;
@@ -992,6 +1022,8 @@ static DisplayFormats typeFormatList(const WatchItem *item)
if (ok) {
formats.append(CompactFloatFormat);
formats.append(ScientificFloatFormat);
formats.append(HexFloatFormat);
formats.append(NormalizedTwoFloatFormat);
}
// Fixed artificial integral types.
@@ -2084,6 +2116,8 @@ QString WatchModel::nameForFormat(int format)
case CompactFloatFormat: return tr("Compact Float");
case ScientificFloatFormat: return tr("Scientific Float");
case HexFloatFormat: return tr("Hexadecimal Float");
case NormalizedTwoFloatFormat: return tr("Normalized, with Power-of-Two Exponent");
}
QTC_CHECK(false);