5656#define FPCONST (x ) x##F
5757#define FPROUND_TO_ONE 0.9999995F
5858#define FPDECEXP 32
59+ #define FPMIN_BUF_SIZE 6 // +9e+99
5960
6061#define FLT_SIGN_MASK 0x80000000
6162#define FLT_EXP_MASK 0x7F800000
@@ -79,6 +80,7 @@ static inline int fp_isless1(float x) { union floatbits fb = {x}; return fb.u <
7980#define FPCONST (x ) x
8081#define FPROUND_TO_ONE 0.999999999995
8182#define FPDECEXP 256
83+ #define FPMIN_BUF_SIZE 7 // +9e+199
8284#include <math.h>
8385#define fp_signbit (x ) signbit(x)
8486#define fp_isspecial (x ) 1
@@ -105,11 +107,11 @@ static const FPTYPE g_neg_pow[] = {
105107int mp_format_float (FPTYPE f , char * buf , size_t buf_size , char fmt , int prec , char sign ) {
106108
107109 char * s = buf ;
108- int buf_remaining = buf_size - 1 ;
109110
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.
113115
114116 if (buf_size >= 2 ) {
115117 * s ++ = '?' ;
@@ -127,7 +129,10 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
127129 * s ++ = sign ;
128130 }
129131 }
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 );
131136
132137 if (fp_isspecial (f )) {
133138 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
226231 e_sign = e_sign_char ;
227232 dec = 0 ;
228233
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 ;
231236 if (fmt == 'g' ) {
232237 prec ++ ;
233238 }
@@ -258,8 +263,8 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
258263 }
259264 }
260265 }
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 ;
263268 }
264269 // If the user specified 'g' format, and e is < prec, then we'll switch
265270 // 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
377382 if (e_sign ) {
378383 * s ++ = e_char ;
379384 * 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 );
381389 * s ++ = '0' + (e % 10 );
382390 }
383391 * s = '\0' ;
0 commit comments