56
56
#define FPCONST (x ) x##F
57
57
#define FPROUND_TO_ONE 0.9999995F
58
58
#define FPDECEXP 32
59
+ #define FPMIN_BUF_SIZE 6 // +9e+99
59
60
60
61
#define FLT_SIGN_MASK 0x80000000
61
62
#define FLT_EXP_MASK 0x7F800000
@@ -79,6 +80,7 @@ static inline int fp_isless1(float x) { union floatbits fb = {x}; return fb.u <
79
80
#define FPCONST (x ) x
80
81
#define FPROUND_TO_ONE 0.999999999995
81
82
#define FPDECEXP 256
83
+ #define FPMIN_BUF_SIZE 7 // +9e+199
82
84
#include <math.h>
83
85
#define fp_signbit (x ) signbit(x)
84
86
#define fp_isspecial (x ) 1
@@ -105,11 +107,11 @@ static const FPTYPE g_neg_pow[] = {
105
107
int mp_format_float (FPTYPE f , char * buf , size_t buf_size , char fmt , int prec , char sign ) {
106
108
107
109
char * s = buf ;
108
- int buf_remaining = buf_size - 1 ;
109
110
110
- if (buf_size < 7 ) {
111
- // Smallest exp notion is -9e+99 which is 6 chars plus terminating
112
- // null.
111
+ if (buf_size <= FPMIN_BUF_SIZE ) {
112
+ // FPMIN_BUF_SIZE is the minimum size needed to store any FP number.
113
+ // If the buffer does not have enough room for this (plus null terminator)
114
+ // then don't try to format the float.
113
115
114
116
if (buf_size >= 2 ) {
115
117
* s ++ = '?' ;
@@ -127,7 +129,10 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
127
129
* s ++ = sign ;
128
130
}
129
131
}
130
- buf_remaining -= (s - buf ); // Adjust for sign
132
+
133
+ // buf_remaining contains bytes available for digits and exponent.
134
+ // It is buf_size minus room for the sign and null byte.
135
+ int buf_remaining = buf_size - 1 - (s - buf );
131
136
132
137
if (fp_isspecial (f )) {
133
138
char uc = fmt & 0x20 ;
@@ -226,8 +231,8 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
226
231
e_sign = e_sign_char ;
227
232
dec = 0 ;
228
233
229
- if (prec > (buf_remaining - 6 )) {
230
- prec = buf_remaining - 6 ;
234
+ if (prec > (buf_remaining - FPMIN_BUF_SIZE )) {
235
+ prec = buf_remaining - FPMIN_BUF_SIZE ;
231
236
if (fmt == 'g' ) {
232
237
prec ++ ;
233
238
}
@@ -258,8 +263,8 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
258
263
}
259
264
}
260
265
}
261
- if (fmt == 'e' && prec > (buf_remaining - 6 )) {
262
- prec = buf_remaining - 6 ;
266
+ if (fmt == 'e' && prec > (buf_remaining - FPMIN_BUF_SIZE )) {
267
+ prec = buf_remaining - FPMIN_BUF_SIZE ;
263
268
}
264
269
// If the user specified 'g' format, and e is < prec, then we'll switch
265
270
// to the fixed format.
@@ -377,7 +382,10 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
377
382
if (e_sign ) {
378
383
* s ++ = e_char ;
379
384
* s ++ = e_sign ;
380
- * s ++ = '0' + (e / 10 );
385
+ if (FPMIN_BUF_SIZE == 7 && e >= 100 ) {
386
+ * s ++ = '0' + (e / 100 );
387
+ }
388
+ * s ++ = '0' + ((e / 10 ) % 10 );
381
389
* s ++ = '0' + (e % 10 );
382
390
}
383
391
* s = '\0' ;
0 commit comments