- /* This is the DELTA array from Knuth.
- DELTA[j] = floor((40+2**(j-1))/(2**j)). */
- static const int delta[8] =
- {
- 0, (40 + 1) / 2, (40 + 2) / 4, (40 + 4) / 8, (40 + 8) / 16,
- (40 + 16) / 32, (40 + 32) / 64, (40 + 64) / 128,
- };
+ assert (fp->w <= 40);
+ if (finite (number))
+ {
+ if (fabs (number) < power10[fp->w])
+ {
+ /* The value may fit in the field. */
+ if (fp->d == 0)
+ {
+ /* There are no decimal places, so there's no way
+ that the value can be shortened. Either it fits
+ or it doesn't. */
+ char buf[40];
+ sprintf (buf, "%*.0f", fp->w, number);
+ if (strlen (buf) <= fp->w)
+ {
+ buf_copy_str_lpad (dst, fp->w, buf);
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ {
+ /* First try to format it with 2 extra decimal
+ places. This gives us a good chance of not
+ needing even more decimal places, but it also
+ avoids wasting too much time formatting more
+ decimal places on the first try. */
+ int result = format_and_round (dst, number, fp, fp->d + 2);
+ if (result >= 0)
+ return result;
+
+ /* 2 extra decimal places weren't enough to
+ correctly round. Try again with the maximum
+ number of places. */
+ return format_and_round (dst, number, fp, LDBL_DIG + 1);
+ }
+ }
+ else
+ {
+ /* The value is too big to fit in the field. */
+ return false;
+ }
+ }
+ else
+ return convert_infinite (dst, fp, number);
+}