adjustments to floating-point printing

This commit is contained in:
caheckman 2020-06-03 17:48:52 -04:00
parent 91ef0680da
commit a027a5cdd8
3 changed files with 46 additions and 13 deletions

View file

@ -71,6 +71,7 @@ FloatFormat::FloatFormat(int4 sz)
jbitimplied = true; jbitimplied = true;
} }
maxexponent = (1<<exp_size)-1; maxexponent = (1<<exp_size)-1;
calcPrecision();
} }
/// \param sign is set to \b true if the value should be negative /// \param sign is set to \b true if the value should be negative
@ -227,6 +228,13 @@ uintb FloatFormat::getNaNEncoding(bool sgn) const
return setSign(res,sgn); return setSign(res,sgn);
} }
void FloatFormat::calcPrecision(void)
{
float val = frac_size * 0.30103;
decimal_precision = (int4)floor(val + 0.5);
}
/// \param encoding is the encoding value /// \param encoding is the encoding value
/// \param type points to the floating-point class, which is passed back /// \param type points to the floating-point class, which is passed back
/// \return the equivalent double value /// \return the equivalent double value
@ -613,4 +621,5 @@ void FloatFormat::restoreXml(const Element *el)
} }
jbitimplied = xml_readbool(el->getAttributeValue("jbitimplied")); jbitimplied = xml_readbool(el->getAttributeValue("jbitimplied"));
maxexponent = (1<<exp_size)-1; maxexponent = (1<<exp_size)-1;
calcPrecision();
} }

View file

@ -46,6 +46,7 @@ private:
int4 exp_size; ///< Number of bits in exponent int4 exp_size; ///< Number of bits in exponent
int4 bias; ///< What to add to real exponent to get encoding int4 bias; ///< What to add to real exponent to get encoding
int4 maxexponent; ///< Maximum possible exponent int4 maxexponent; ///< Maximum possible exponent
int4 decimal_precision; ///< Number of decimal digits of precision
bool jbitimplied; ///< Set to \b true if integer bit of 1 is assumed bool jbitimplied; ///< Set to \b true if integer bit of 1 is assumed
static double createFloat(bool sign,uintb signif,int4 exp); ///< Create a double given sign, fractional, and exponent static double createFloat(bool sign,uintb signif,int4 exp); ///< Create a double given sign, fractional, and exponent
static floatclass extractExpSig(double x,bool *sgn,uintb *signif,int4 *exp); static floatclass extractExpSig(double x,bool *sgn,uintb *signif,int4 *exp);
@ -55,12 +56,14 @@ private:
uintb getZeroEncoding(bool sgn) const; ///< Get an encoded zero value uintb getZeroEncoding(bool sgn) const; ///< Get an encoded zero value
uintb getInfinityEncoding(bool sgn) const; ///< Get an encoded infinite value uintb getInfinityEncoding(bool sgn) const; ///< Get an encoded infinite value
uintb getNaNEncoding(bool sgn) const; ///< Get an encoded NaN value uintb getNaNEncoding(bool sgn) const; ///< Get an encoded NaN value
void calcPrecision(void); ///< Calculate the decimal precision of this format
public: public:
FloatFormat(void) {} ///< Construct for use with restoreXml() FloatFormat(void) {} ///< Construct for use with restoreXml()
FloatFormat(int4 sz); ///< Construct default IEEE 754 standard settings FloatFormat(int4 sz); ///< Construct default IEEE 754 standard settings
int4 getSize(void) const { return size; } ///< Get the size of the encoding in bytes int4 getSize(void) const { return size; } ///< Get the size of the encoding in bytes
double getHostFloat(uintb encoding,floatclass *type) const; ///< Convert an encoding into host's double double getHostFloat(uintb encoding,floatclass *type) const; ///< Convert an encoding into host's double
uintb getEncoding(double host) const; ///< Convert host's double into \b this encoding uintb getEncoding(double host) const; ///< Convert host's double into \b this encoding
int4 getDecimalPrecision(void) const { return decimal_precision; } ///< Get number of digits of precision
uintb convertEncoding(uintb encoding,const FloatFormat *formin) const; ///< Convert between two different formats uintb convertEncoding(uintb encoding,const FloatFormat *formin) const; ///< Convert between two different formats
uintb extractFractionalCode(uintb x) const; ///< Extract the fractional part of the encoding uintb extractFractionalCode(uintb x) const; ///< Extract the fractional part of the encoding

View file

@ -1087,38 +1087,59 @@ void PrintC::push_integer(uintb val,int4 sz,bool sign,
/// \param op is the PcodeOp using the value /// \param op is the PcodeOp using the value
void PrintC::push_float(uintb val,int4 sz,const Varnode *vn,const PcodeOp *op) void PrintC::push_float(uintb val,int4 sz,const Varnode *vn,const PcodeOp *op)
{ {
ostringstream t; string token;
const FloatFormat *format = glb->translate->getFloatFormat(sz); const FloatFormat *format = glb->translate->getFloatFormat(sz);
if (format == (const FloatFormat *)0) { if (format == (const FloatFormat *)0) {
t << "FLOAT_UNKNOWN"; token = "FLOAT_UNKNOWN";
} }
else { else {
FloatFormat::floatclass type; FloatFormat::floatclass type;
double floatval = format->getHostFloat(val,&type); double floatval = format->getHostFloat(val,&type);
if (type == FloatFormat::infinity) { if (type == FloatFormat::infinity) {
if (format->extractSign(val)) if (format->extractSign(val))
t << '-'; token = "-INFINITY";
t << "INFINITY"; else
token = "INFINITY";
} }
else if (type == FloatFormat::nan) { else if (type == FloatFormat::nan) {
if (format->extractSign(val)) if (format->extractSign(val))
t << '-'; token = "-NAN";
t << "NAN"; else
token = "NAN";
} }
else { else {
if ((mods & force_scinote)!=0) ostringstream t;
if ((mods & force_scinote)!=0) {
t.setf( ios::scientific ); // Set to scientific notation t.setf( ios::scientific ); // Set to scientific notation
else t.precision(format->getDecimalPrecision()-1);
t.setf( ios::fixed ); // Otherwise use fixed notation t << floatval;
t.precision(8); // Number of digits of precision token = t.str();
t << floatval; }
else {
// Try to print "minimal" accurate representation of the float
t.unsetf( ios::floatfield ); // Use "default" notation
t.precision(format->getDecimalPrecision());
t << floatval;
token = t.str();
bool looksLikeFloat = false;
for(int4 i=0;i<token.size();++i) {
char c = token[i];
if (c == '.' || c == 'e') {
looksLikeFloat = true;
break;
}
}
if (!looksLikeFloat) {
token += ".0"; // Force token to look like a floating-point value
}
}
} }
} }
if (vn==(const Varnode *)0) if (vn==(const Varnode *)0)
pushAtom(Atom(t.str(),syntax,EmitXml::const_color,op)); pushAtom(Atom(token,syntax,EmitXml::const_color,op));
else else
pushAtom(Atom(t.str(),vartoken,EmitXml::const_color,op,vn)); pushAtom(Atom(token,vartoken,EmitXml::const_color,op,vn));
} }
void PrintC::printUnicode(ostream &s,int4 onechar) const void PrintC::printUnicode(ostream &s,int4 onechar) const