Skip to content

Commit dffb4ef

Browse files
authored
Merge pull request #914 from diffblue/pretty-float
Pretty float
2 parents 2f0ba52 + 2d31501 commit dffb4ef

File tree

4 files changed

+57
-10
lines changed

4 files changed

+57
-10
lines changed

regression/cbmc/printf1/main.c

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdio.h>
2+
#include <assert.h>
3+
4+
int main()
5+
{
6+
printf("PRINT d1 %d, %d\n", 123, -123);
7+
printf("PRINT g1 %g, %g, %g, %g\n", 123.0, -123.0, 123.123, 0.123);
8+
printf("PRINT e1 %e, %e, %e, %e\n", 123.0, -123.0, 123.123, 0.123);
9+
printf("PRINT f1 %f, %f, %f, %f\n", 123.0, -123.0, 123.123, 0.123);
10+
assert(0);
11+
}

regression/cbmc/printf1/test.desc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
--trace
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^PRINT d1 123, -123$
7+
^PRINT g1 123, -123, 123\.123, 0\.123$
8+
^PRINT e1 1\.230000e\+2, -1\.230000e\+2, 1\.231230e\+2, 1\.230000e-1$
9+
^PRINT f1 123\.000000, -123\.000000, 123\.123000, 0\.123000$
10+
--
11+
^warning: ignoring

src/ansi-c/printf_formatter.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,18 @@ void printf_formattert::process_format(std::ostream &out)
159159
out << ch;
160160
break;
161161

162+
case 'e':
163+
case 'E':
164+
format_constant.style=format_spect::stylet::SCIENTIFIC;
165+
if(next_operand==operands.end())
166+
break;
167+
out << format_constant(
168+
make_type(*(next_operand++), double_type()));
169+
break;
170+
162171
case 'f':
163172
case 'F':
173+
format_constant.style=format_spect::stylet::DECIMAL;
164174
if(next_operand==operands.end())
165175
break;
166176
out << format_constant(
@@ -169,6 +179,7 @@ void printf_formattert::process_format(std::ostream &out)
169179

170180
case 'g':
171181
case 'G':
182+
format_constant.style=format_spect::stylet::AUTOMATIC;
172183
if(format_constant.precision==0)
173184
format_constant.precision=1;
174185
if(next_operand==operands.end())

src/util/ieee_float.cpp

+24-10
Original file line numberDiff line numberDiff line change
@@ -161,25 +161,39 @@ std::string ieee_floatt::format(const format_spect &format_spec) const
161161

162162
case format_spect::stylet::AUTOMATIC:
163163
{
164+
// On Linux, the man page says:
164165
// "Style e is used if the exponent from its conversion
165166
// is less than -4 or greater than or equal to the precision."
167+
//
168+
// On BSD, it's
169+
// "The argument is printed in style f (F) or in style e (E)
170+
// whichever gives full precision in minimum space."
166171

167172
mp_integer _exponent, _fraction;
168173
extract_base10(_fraction, _exponent);
169174

170-
if(_exponent>=0)
175+
mp_integer adjusted_exponent=base10_digits(_fraction)+_exponent;
176+
177+
if(adjusted_exponent>=format_spec.precision ||
178+
adjusted_exponent<-4)
171179
{
172-
if(base10_digits(_fraction)+_exponent>=format_spec.precision)
173-
result+=to_string_scientific(format_spec.precision);
174-
else
175-
result+=to_string_decimal(format_spec.precision);
180+
result+=to_string_scientific(format_spec.precision);
176181
}
177-
else // _exponent<0
182+
else
178183
{
179-
if(true) // base10_digits(fraction)+_exponent<-4)
180-
result+=to_string_scientific(format_spec.precision);
181-
else
182-
result+=to_string_decimal(format_spec.precision);
184+
result+=to_string_decimal(format_spec.precision);
185+
186+
// Implementations tested also appear to suppress trailing zeros
187+
// and trailing dots.
188+
189+
{
190+
std::size_t trunc_pos=result.find_last_not_of('0');
191+
if(trunc_pos!=std::string::npos)
192+
result.resize(trunc_pos+1);
193+
}
194+
195+
if(!result.empty() && result.back()=='.')
196+
result.resize(result.size()-1);
183197
}
184198
}
185199
break;

0 commit comments

Comments
 (0)