PostgreSQL Source Code  git master
f2s.c File Reference
#include "postgres.h"
#include "common/shortest_dec.h"
#include "digit_table.h"
#include "ryu_common.h"
Include dependency graph for f2s.c:

Go to the source code of this file.

Data Structures

struct  floating_decimal_32
 

Macros

#define FLOAT_MANTISSA_BITS   23
 
#define FLOAT_EXPONENT_BITS   8
 
#define FLOAT_BIAS   127
 
#define FLOAT_POW5_INV_BITCOUNT   59
 
#define FLOAT_POW5_BITCOUNT   61
 

Typedefs

typedef struct floating_decimal_32 floating_decimal_32
 

Functions

static uint32 pow5Factor (uint32 value)
 
static bool multipleOfPowerOf5 (const uint32 value, const uint32 p)
 
static bool multipleOfPowerOf2 (const uint32 value, const uint32 p)
 
static uint32 mulShift (const uint32 m, const uint64 factor, const int32 shift)
 
static uint32 mulPow5InvDivPow2 (const uint32 m, const uint32 q, const int32 j)
 
static uint32 mulPow5divPow2 (const uint32 m, const uint32 i, const int32 j)
 
static uint32 decimalLength (const uint32 v)
 
static floating_decimal_32 f2d (const uint32 ieeeMantissa, const uint32 ieeeExponent)
 
static int to_chars_f (const floating_decimal_32 v, const uint32 olength, char *const result)
 
static int to_chars (const floating_decimal_32 v, const bool sign, char *const result)
 
static bool f2d_small_int (const uint32 ieeeMantissa, const uint32 ieeeExponent, floating_decimal_32 *v)
 
int float_to_shortest_decimal_bufn (float f, char *result)
 
int float_to_shortest_decimal_buf (float f, char *result)
 
char * float_to_shortest_decimal (float f)
 

Variables

static const uint64 FLOAT_POW5_INV_SPLIT [31]
 
static const uint64 FLOAT_POW5_SPLIT [47]
 

Macro Definition Documentation

◆ FLOAT_BIAS

#define FLOAT_BIAS   127

Definition at line 47 of file f2s.c.

Referenced by f2d(), and f2d_small_int().

◆ FLOAT_EXPONENT_BITS

#define FLOAT_EXPONENT_BITS   8

Definition at line 46 of file f2s.c.

Referenced by float_to_shortest_decimal_bufn().

◆ FLOAT_MANTISSA_BITS

#define FLOAT_MANTISSA_BITS   23

Definition at line 45 of file f2s.c.

Referenced by f2d(), f2d_small_int(), and float_to_shortest_decimal_bufn().

◆ FLOAT_POW5_BITCOUNT

#define FLOAT_POW5_BITCOUNT   61

Definition at line 64 of file f2s.c.

Referenced by f2d().

◆ FLOAT_POW5_INV_BITCOUNT

#define FLOAT_POW5_INV_BITCOUNT   59

Definition at line 53 of file f2s.c.

Referenced by f2d().

Typedef Documentation

◆ floating_decimal_32

Function Documentation

◆ decimalLength()

static uint32 decimalLength ( const uint32  v)
inlinestatic

Definition at line 174 of file f2s.c.

References Assert.

Referenced by to_chars().

175 {
176  /* Function precondition: v is not a 10-digit number. */
177  /* (9 digits are sufficient for round-tripping.) */
178  Assert(v < 1000000000);
179  if (v >= 100000000)
180  {
181  return 9;
182  }
183  if (v >= 10000000)
184  {
185  return 8;
186  }
187  if (v >= 1000000)
188  {
189  return 7;
190  }
191  if (v >= 100000)
192  {
193  return 6;
194  }
195  if (v >= 10000)
196  {
197  return 5;
198  }
199  if (v >= 1000)
200  {
201  return 4;
202  }
203  if (v >= 100)
204  {
205  return 3;
206  }
207  if (v >= 10)
208  {
209  return 2;
210  }
211  return 1;
212 }
#define Assert(condition)
Definition: c.h:738

◆ f2d()

static floating_decimal_32 f2d ( const uint32  ieeeMantissa,
const uint32  ieeeExponent 
)
inlinestatic

Definition at line 222 of file f2s.c.

References floating_decimal_32::exponent, fd(), FLOAT_BIAS, FLOAT_MANTISSA_BITS, FLOAT_POW5_BITCOUNT, FLOAT_POW5_INV_BITCOUNT, i, log10Pow2(), log10Pow5(), floating_decimal_32::mantissa, mulPow5divPow2(), mulPow5InvDivPow2(), multipleOfPowerOf2(), multipleOfPowerOf5(), output(), and pow5bits().

Referenced by float_to_shortest_decimal_bufn().

223 {
224  int32 e2;
225  uint32 m2;
226 
227  if (ieeeExponent == 0)
228  {
229  /* We subtract 2 so that the bounds computation has 2 additional bits. */
230  e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
231  m2 = ieeeMantissa;
232  }
233  else
234  {
235  e2 = ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2;
236  m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa;
237  }
238 
239 #if STRICTLY_SHORTEST
240  const bool even = (m2 & 1) == 0;
241  const bool acceptBounds = even;
242 #else
243  const bool acceptBounds = false;
244 #endif
245 
246  /* Step 2: Determine the interval of legal decimal representations. */
247  const uint32 mv = 4 * m2;
248  const uint32 mp = 4 * m2 + 2;
249 
250  /* Implicit bool -> int conversion. True is 1, false is 0. */
251  const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1;
252  const uint32 mm = 4 * m2 - 1 - mmShift;
253 
254  /* Step 3: Convert to a decimal power base using 64-bit arithmetic. */
255  uint32 vr,
256  vp,
257  vm;
258  int32 e10;
259  bool vmIsTrailingZeros = false;
260  bool vrIsTrailingZeros = false;
261  uint8 lastRemovedDigit = 0;
262 
263  if (e2 >= 0)
264  {
265  const uint32 q = log10Pow2(e2);
266 
267  e10 = q;
268 
269  const int32 k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1;
270  const int32 i = -e2 + q + k;
271 
272  vr = mulPow5InvDivPow2(mv, q, i);
273  vp = mulPow5InvDivPow2(mp, q, i);
274  vm = mulPow5InvDivPow2(mm, q, i);
275 
276  if (q != 0 && (vp - 1) / 10 <= vm / 10)
277  {
278  /*
279  * We need to know one removed digit even if we are not going to
280  * loop below. We could use q = X - 1 above, except that would
281  * require 33 bits for the result, and we've found that 32-bit
282  * arithmetic is faster even on 64-bit machines.
283  */
284  const int32 l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q - 1) - 1;
285 
286  lastRemovedDigit = (uint8) (mulPow5InvDivPow2(mv, q - 1, -e2 + q - 1 + l) % 10);
287  }
288  if (q <= 9)
289  {
290  /*
291  * The largest power of 5 that fits in 24 bits is 5^10, but q <= 9
292  * seems to be safe as well.
293  *
294  * Only one of mp, mv, and mm can be a multiple of 5, if any.
295  */
296  if (mv % 5 == 0)
297  {
298  vrIsTrailingZeros = multipleOfPowerOf5(mv, q);
299  }
300  else if (acceptBounds)
301  {
302  vmIsTrailingZeros = multipleOfPowerOf5(mm, q);
303  }
304  else
305  {
306  vp -= multipleOfPowerOf5(mp, q);
307  }
308  }
309  }
310  else
311  {
312  const uint32 q = log10Pow5(-e2);
313 
314  e10 = q + e2;
315 
316  const int32 i = -e2 - q;
317  const int32 k = pow5bits(i) - FLOAT_POW5_BITCOUNT;
318  int32 j = q - k;
319 
320  vr = mulPow5divPow2(mv, i, j);
321  vp = mulPow5divPow2(mp, i, j);
322  vm = mulPow5divPow2(mm, i, j);
323 
324  if (q != 0 && (vp - 1) / 10 <= vm / 10)
325  {
326  j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT);
327  lastRemovedDigit = (uint8) (mulPow5divPow2(mv, i + 1, j) % 10);
328  }
329  if (q <= 1)
330  {
331  /*
332  * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q
333  * trailing 0 bits.
334  */
335  /* mv = 4 * m2, so it always has at least two trailing 0 bits. */
336  vrIsTrailingZeros = true;
337  if (acceptBounds)
338  {
339  /*
340  * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff
341  * mmShift == 1.
342  */
343  vmIsTrailingZeros = mmShift == 1;
344  }
345  else
346  {
347  /*
348  * mp = mv + 2, so it always has at least one trailing 0 bit.
349  */
350  --vp;
351  }
352  }
353  else if (q < 31)
354  {
355  /* TODO(ulfjack):Use a tighter bound here. */
356  vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1);
357  }
358  }
359 
360  /*
361  * Step 4: Find the shortest decimal representation in the interval of
362  * legal representations.
363  */
364  uint32 removed = 0;
365  uint32 output;
366 
367  if (vmIsTrailingZeros || vrIsTrailingZeros)
368  {
369  /* General case, which happens rarely (~4.0%). */
370  while (vp / 10 > vm / 10)
371  {
372  vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0;
373  vrIsTrailingZeros &= lastRemovedDigit == 0;
374  lastRemovedDigit = (uint8) (vr % 10);
375  vr /= 10;
376  vp /= 10;
377  vm /= 10;
378  ++removed;
379  }
380  if (vmIsTrailingZeros)
381  {
382  while (vm % 10 == 0)
383  {
384  vrIsTrailingZeros &= lastRemovedDigit == 0;
385  lastRemovedDigit = (uint8) (vr % 10);
386  vr /= 10;
387  vp /= 10;
388  vm /= 10;
389  ++removed;
390  }
391  }
392 
393  if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0)
394  {
395  /* Round even if the exact number is .....50..0. */
396  lastRemovedDigit = 4;
397  }
398 
399  /*
400  * We need to take vr + 1 if vr is outside bounds or we need to round
401  * up.
402  */
403  output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5);
404  }
405  else
406  {
407  /*
408  * Specialized for the common case (~96.0%). Percentages below are
409  * relative to this.
410  *
411  * Loop iterations below (approximately): 0: 13.6%, 1: 70.7%, 2:
412  * 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01%
413  */
414  while (vp / 10 > vm / 10)
415  {
416  lastRemovedDigit = (uint8) (vr % 10);
417  vr /= 10;
418  vp /= 10;
419  vm /= 10;
420  ++removed;
421  }
422 
423  /*
424  * We need to take vr + 1 if vr is outside bounds or we need to round
425  * up.
426  */
427  output = vr + (vr == vm || lastRemovedDigit >= 5);
428  }
429 
430  const int32 exp = e10 + removed;
431 
433 
434  fd.exponent = exp;
435  fd.mantissa = output;
436  return fd;
437 }
static uint32 mulPow5divPow2(const uint32 m, const uint32 i, const int32 j)
Definition: f2s.c:168
static void output(uint64 loop_count)
#define FLOAT_MANTISSA_BITS
Definition: f2s.c:45
unsigned char uint8
Definition: c.h:365
#define FLOAT_POW5_INV_BITCOUNT
Definition: f2s.c:53
#define FLOAT_BIAS
Definition: f2s.c:47
static int fd(const char *x, int i)
Definition: preproc-init.c:105
signed int int32
Definition: c.h:355
static bool multipleOfPowerOf5(const uint32 value, const uint32 p)
Definition: f2s.c:102
unsigned int uint32
Definition: c.h:367
static int32 log10Pow2(const int32 e)
Definition: ryu_common.h:70
uint32 mantissa
Definition: f2s.c:217
static uint32 pow5bits(const int32 e)
Definition: ryu_common.h:54
int32 exponent
Definition: f2s.c:218
static bool multipleOfPowerOf2(const uint32 value, const uint32 p)
Definition: f2s.c:109
static int32 log10Pow5(const int32 e)
Definition: ryu_common.h:83
static uint32 mulPow5InvDivPow2(const uint32 m, const uint32 q, const int32 j)
Definition: f2s.c:162
int i
#define FLOAT_POW5_BITCOUNT
Definition: f2s.c:64

◆ f2d_small_int()

static bool f2d_small_int ( const uint32  ieeeMantissa,
const uint32  ieeeExponent,
floating_decimal_32 v 
)
inlinestatic

Definition at line 689 of file f2s.c.

References floating_decimal_32::exponent, FLOAT_BIAS, FLOAT_MANTISSA_BITS, and floating_decimal_32::mantissa.

Referenced by float_to_shortest_decimal_bufn().

692 {
693  const int32 e2 = (int32) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS;
694 
695  /*
696  * Avoid using multiple "return false;" here since it tends to provoke the
697  * compiler into inlining multiple copies of f2d, which is undesirable.
698  */
699 
700  if (e2 >= -FLOAT_MANTISSA_BITS && e2 <= 0)
701  {
702  /*----
703  * Since 2^23 <= m2 < 2^24 and 0 <= -e2 <= 23:
704  * 1 <= f = m2 / 2^-e2 < 2^24.
705  *
706  * Test if the lower -e2 bits of the significand are 0, i.e. whether
707  * the fraction is 0. We can use ieeeMantissa here, since the implied
708  * 1 bit can never be tested by this; the implied 1 can only be part
709  * of a fraction if e2 < -FLOAT_MANTISSA_BITS which we already
710  * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -24)
711  */
712  const uint32 mask = (1U << -e2) - 1;
713  const uint32 fraction = ieeeMantissa & mask;
714 
715  if (fraction == 0)
716  {
717  /*----
718  * f is an integer in the range [1, 2^24).
719  * Note: mantissa might contain trailing (decimal) 0's.
720  * Note: since 2^24 < 10^9, there is no need to adjust
721  * decimalLength().
722  */
723  const uint32 m2 = (1U << FLOAT_MANTISSA_BITS) | ieeeMantissa;
724 
725  v->mantissa = m2 >> -e2;
726  v->exponent = 0;
727  return true;
728  }
729  }
730 
731  return false;
732 }
#define FLOAT_MANTISSA_BITS
Definition: f2s.c:45
#define FLOAT_BIAS
Definition: f2s.c:47
signed int int32
Definition: c.h:355
unsigned int uint32
Definition: c.h:367
uint32 mantissa
Definition: f2s.c:217
int32 exponent
Definition: f2s.c:218

◆ float_to_shortest_decimal()

char* float_to_shortest_decimal ( float  f)

Definition at line 797 of file f2s.c.

References FLOAT_SHORTEST_DECIMAL_LEN, float_to_shortest_decimal_buf(), and palloc().

798 {
799  char *const result = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN);
800 
802  return result;
803 }
#define FLOAT_SHORTEST_DECIMAL_LEN
Definition: shortest_dec.h:57
int float_to_shortest_decimal_buf(float f, char *result)
Definition: f2s.c:780
void * palloc(Size size)
Definition: mcxt.c:949

◆ float_to_shortest_decimal_buf()

int float_to_shortest_decimal_buf ( float  f,
char *  result 
)

Definition at line 780 of file f2s.c.

References Assert, FLOAT_SHORTEST_DECIMAL_LEN, and float_to_shortest_decimal_bufn().

Referenced by float4out(), and float_to_shortest_decimal().

781 {
782  const int index = float_to_shortest_decimal_bufn(f, result);
783 
784  /* Terminate the string. */
786  result[index] = '\0';
787  return index;
788 }
#define FLOAT_SHORTEST_DECIMAL_LEN
Definition: shortest_dec.h:57
Definition: type.h:89
#define Assert(condition)
Definition: c.h:738
int float_to_shortest_decimal_bufn(float f, char *result)
Definition: f2s.c:742

◆ float_to_shortest_decimal_bufn()

int float_to_shortest_decimal_bufn ( float  f,
char *  result 
)

Definition at line 742 of file f2s.c.

References copy_special_str(), f2d(), f2d_small_int(), FLOAT_EXPONENT_BITS, FLOAT_MANTISSA_BITS, float_to_bits(), and to_chars().

Referenced by float_to_shortest_decimal_buf().

743 {
744  /*
745  * Step 1: Decode the floating-point number, and unify normalized and
746  * subnormal cases.
747  */
748  const uint32 bits = float_to_bits(f);
749 
750  /* Decode bits into sign, mantissa, and exponent. */
751  const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
752  const uint32 ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1);
753  const uint32 ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1);
754 
755  /* Case distinction; exit early for the easy cases. */
756  if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0))
757  {
758  return copy_special_str(result, ieeeSign, (ieeeExponent != 0), (ieeeMantissa != 0));
759  }
760 
762  const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v);
763 
764  if (!isSmallInt)
765  {
766  v = f2d(ieeeMantissa, ieeeExponent);
767  }
768 
769  return to_chars(v, ieeeSign, result);
770 }
static uint32 float_to_bits(const float f)
Definition: ryu_common.h:116
#define FLOAT_MANTISSA_BITS
Definition: f2s.c:45
unsigned int uint32
Definition: c.h:367
static int to_chars(const floating_decimal_32 v, const bool sign, char *const result)
Definition: f2s.c:563
static bool f2d_small_int(const uint32 ieeeMantissa, const uint32 ieeeExponent, floating_decimal_32 *v)
Definition: f2s.c:689
static int copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa)
Definition: ryu_common.h:95
#define FLOAT_EXPONENT_BITS
Definition: f2s.c:46
static floating_decimal_32 f2d(const uint32 ieeeMantissa, const uint32 ieeeExponent)
Definition: f2s.c:222

◆ mulPow5divPow2()

static uint32 mulPow5divPow2 ( const uint32  m,
const uint32  i,
const int32  j 
)
inlinestatic

Definition at line 168 of file f2s.c.

References FLOAT_POW5_SPLIT, and mulShift().

Referenced by f2d().

169 {
170  return mulShift(m, FLOAT_POW5_SPLIT[i], j);
171 }
static const uint64 FLOAT_POW5_SPLIT[47]
Definition: f2s.c:65
static uint32 mulShift(const uint32 m, const uint64 factor, const int32 shift)
Definition: f2s.c:120
int i

◆ mulPow5InvDivPow2()

static uint32 mulPow5InvDivPow2 ( const uint32  m,
const uint32  q,
const int32  j 
)
inlinestatic

Definition at line 162 of file f2s.c.

References FLOAT_POW5_INV_SPLIT, and mulShift().

Referenced by f2d().

163 {
164  return mulShift(m, FLOAT_POW5_INV_SPLIT[q], j);
165 }
static uint32 mulShift(const uint32 m, const uint64 factor, const int32 shift)
Definition: f2s.c:120
static const uint64 FLOAT_POW5_INV_SPLIT[31]
Definition: f2s.c:54

◆ mulShift()

static uint32 mulShift ( const uint32  m,
const uint64  factor,
const int32  shift 
)
inlinestatic

Definition at line 120 of file f2s.c.

References Assert, and PG_UINT32_MAX.

Referenced by mulPow5divPow2(), mulPow5InvDivPow2(), and multipleOfPowerOf2().

121 {
122  /*
123  * The casts here help MSVC to avoid calls to the __allmul library
124  * function.
125  */
126  const uint32 factorLo = (uint32) (factor);
127  const uint32 factorHi = (uint32) (factor >> 32);
128  const uint64 bits0 = (uint64) m * factorLo;
129  const uint64 bits1 = (uint64) m * factorHi;
130 
131  Assert(shift > 32);
132 
133 #ifdef RYU_32_BIT_PLATFORM
134 
135  /*
136  * On 32-bit platforms we can avoid a 64-bit shift-right since we only
137  * need the upper 32 bits of the result and the shift value is > 32.
138  */
139  const uint32 bits0Hi = (uint32) (bits0 >> 32);
140  uint32 bits1Lo = (uint32) (bits1);
141  uint32 bits1Hi = (uint32) (bits1 >> 32);
142 
143  bits1Lo += bits0Hi;
144  bits1Hi += (bits1Lo < bits0Hi);
145 
146  const int32 s = shift - 32;
147 
148  return (bits1Hi << (32 - s)) | (bits1Lo >> s);
149 
150 #else /* RYU_32_BIT_PLATFORM */
151 
152  const uint64 sum = (bits0 >> 32) + bits1;
153  const uint64 shiftedSum = sum >> (shift - 32);
154 
155  Assert(shiftedSum <= PG_UINT32_MAX);
156  return (uint32) shiftedSum;
157 
158 #endif /* RYU_32_BIT_PLATFORM */
159 }
#define PG_UINT32_MAX
Definition: c.h:451
signed int int32
Definition: c.h:355
unsigned int uint32
Definition: c.h:367
#define Assert(condition)
Definition: c.h:738

◆ multipleOfPowerOf2()

static bool multipleOfPowerOf2 ( const uint32  value,
const uint32  p 
)
inlinestatic

Definition at line 109 of file f2s.c.

Referenced by f2d().

110 {
111  /* return __builtin_ctz(value) >= p; */
112  return (value & ((1u << p) - 1)) == 0;
113 }
static struct @143 value

◆ multipleOfPowerOf5()

static bool multipleOfPowerOf5 ( const uint32  value,
const uint32  p 
)
inlinestatic

Definition at line 102 of file f2s.c.

References pow5Factor().

Referenced by f2d().

103 {
104  return pow5Factor(value) >= p;
105 }
static uint32 pow5Factor(uint32 value)
Definition: f2s.c:81
static struct @143 value

◆ pow5Factor()

static uint32 pow5Factor ( uint32  value)
inlinestatic

Definition at line 81 of file f2s.c.

References Assert.

Referenced by multipleOfPowerOf5().

82 {
83  uint32 count = 0;
84 
85  for (;;)
86  {
87  Assert(value != 0);
88  const uint32 q = value / 5;
89  const uint32 r = value % 5;
90 
91  if (r != 0)
92  break;
93 
94  value = q;
95  ++count;
96  }
97  return count;
98 }
unsigned int uint32
Definition: c.h:367
static struct @143 value
#define Assert(condition)
Definition: c.h:738

◆ to_chars()

static int to_chars ( const floating_decimal_32  v,
const bool  sign,
char *const  result 
)
inlinestatic

Definition at line 563 of file f2s.c.

References decimalLength(), DIGIT_TABLE, floating_decimal_32::exponent, i, floating_decimal_32::mantissa, output(), sign, and to_chars_f().

Referenced by float_to_shortest_decimal_bufn().

564 {
565  /* Step 5: Print the decimal representation. */
566  int index = 0;
567 
568  uint32 output = v.mantissa;
569  uint32 olength = decimalLength(output);
570  int32 exp = v.exponent + olength - 1;
571 
572  if (sign)
573  result[index++] = '-';
574 
575  /*
576  * The thresholds for fixed-point output are chosen to match printf
577  * defaults. Beware that both the code of to_chars_f and the value of
578  * FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds.
579  */
580  if (exp >= -4 && exp < 6)
581  return to_chars_f(v, olength, result + index) + sign;
582 
583  /*
584  * If v.exponent is exactly 0, we might have reached here via the small
585  * integer fast path, in which case v.mantissa might contain trailing
586  * (decimal) zeros. For scientific notation we need to move these zeros
587  * into the exponent. (For fixed point this doesn't matter, which is why
588  * we do this here rather than above.)
589  *
590  * Since we already calculated the display exponent (exp) above based on
591  * the old decimal length, that value does not change here. Instead, we
592  * just reduce the display length for each digit removed.
593  *
594  * If we didn't get here via the fast path, the raw exponent will not
595  * usually be 0, and there will be no trailing zeros, so we pay no more
596  * than one div10/multiply extra cost. We claw back half of that by
597  * checking for divisibility by 2 before dividing by 10.
598  */
599  if (v.exponent == 0)
600  {
601  while ((output & 1) == 0)
602  {
603  const uint32 q = output / 10;
604  const uint32 r = output - 10 * q;
605 
606  if (r != 0)
607  break;
608  output = q;
609  --olength;
610  }
611  }
612 
613  /*----
614  * Print the decimal digits.
615  * The following code is equivalent to:
616  *
617  * for (uint32 i = 0; i < olength - 1; ++i) {
618  * const uint32 c = output % 10; output /= 10;
619  * result[index + olength - i] = (char) ('0' + c);
620  * }
621  * result[index] = '0' + output % 10;
622  */
623  uint32 i = 0;
624 
625  while (output >= 10000)
626  {
627  const uint32 c = output - 10000 * (output / 10000);
628  const uint32 c0 = (c % 100) << 1;
629  const uint32 c1 = (c / 100) << 1;
630 
631  output /= 10000;
632 
633  memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2);
634  memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2);
635  i += 4;
636  }
637  if (output >= 100)
638  {
639  const uint32 c = (output % 100) << 1;
640 
641  output /= 100;
642  memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2);
643  i += 2;
644  }
645  if (output >= 10)
646  {
647  const uint32 c = output << 1;
648 
649  /*
650  * We can't use memcpy here: the decimal dot goes between these two
651  * digits.
652  */
653  result[index + olength - i] = DIGIT_TABLE[c + 1];
654  result[index] = DIGIT_TABLE[c];
655  }
656  else
657  {
658  result[index] = (char) ('0' + output);
659  }
660 
661  /* Print decimal point if needed. */
662  if (olength > 1)
663  {
664  result[index + 1] = '.';
665  index += olength + 1;
666  }
667  else
668  {
669  ++index;
670  }
671 
672  /* Print the exponent. */
673  result[index++] = 'e';
674  if (exp < 0)
675  {
676  result[index++] = '-';
677  exp = -exp;
678  }
679  else
680  result[index++] = '+';
681 
682  memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
683  index += 2;
684 
685  return index;
686 }
static void output(uint64 loop_count)
signed int int32
Definition: c.h:355
Definition: type.h:89
char sign
Definition: informix.c:668
char * c
unsigned int uint32
Definition: c.h:367
uint32 mantissa
Definition: f2s.c:217
static uint32 decimalLength(const uint32 v)
Definition: f2s.c:174
int32 exponent
Definition: f2s.c:218
int i
static int to_chars_f(const floating_decimal_32 v, const uint32 olength, char *const result)
Definition: f2s.c:440
static const char DIGIT_TABLE[200]
Definition: numutils.c:29

◆ to_chars_f()

static int to_chars_f ( const floating_decimal_32  v,
const uint32  olength,
char *const  result 
)
inlinestatic

Definition at line 440 of file f2s.c.

References Assert, DIGIT_TABLE, floating_decimal_32::exponent, i, floating_decimal_32::mantissa, and output().

Referenced by to_chars().

441 {
442  /* Step 5: Print the decimal representation. */
443  int index = 0;
444 
445  uint32 output = v.mantissa;
446  int32 exp = v.exponent;
447 
448  /*----
449  * On entry, mantissa * 10^exp is the result to be output.
450  * Caller has already done the - sign if needed.
451  *
452  * We want to insert the point somewhere depending on the output length
453  * and exponent, which might mean adding zeros:
454  *
455  * exp | format
456  * 1+ | ddddddddd000000
457  * 0 | ddddddddd
458  * -1 .. -len+1 | dddddddd.d to d.ddddddddd
459  * -len ... | 0.ddddddddd to 0.000dddddd
460  */
461  uint32 i = 0;
462  int32 nexp = exp + olength;
463 
464  if (nexp <= 0)
465  {
466  /* -nexp is number of 0s to add after '.' */
467  Assert(nexp >= -3);
468  /* 0.000ddddd */
469  index = 2 - nexp;
470  /* copy 8 bytes rather than 5 to let compiler optimize */
471  memcpy(result, "0.000000", 8);
472  }
473  else if (exp < 0)
474  {
475  /*
476  * dddd.dddd; leave space at the start and move the '.' in after
477  */
478  index = 1;
479  }
480  else
481  {
482  /*
483  * We can save some code later by pre-filling with zeros. We know that
484  * there can be no more than 6 output digits in this form, otherwise
485  * we would not choose fixed-point output. memset 8 rather than 6
486  * bytes to let the compiler optimize it.
487  */
488  Assert(exp < 6 && exp + olength <= 6);
489  memset(result, '0', 8);
490  }
491 
492  while (output >= 10000)
493  {
494  const uint32 c = output - 10000 * (output / 10000);
495  const uint32 c0 = (c % 100) << 1;
496  const uint32 c1 = (c / 100) << 1;
497 
498  output /= 10000;
499 
500  memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2);
501  memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2);
502  i += 4;
503  }
504  if (output >= 100)
505  {
506  const uint32 c = (output % 100) << 1;
507 
508  output /= 100;
509  memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2);
510  i += 2;
511  }
512  if (output >= 10)
513  {
514  const uint32 c = output << 1;
515 
516  memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2);
517  }
518  else
519  {
520  result[index] = (char) ('0' + output);
521  }
522 
523  if (index == 1)
524  {
525  /*
526  * nexp is 1..6 here, representing the number of digits before the
527  * point. A value of 7+ is not possible because we switch to
528  * scientific notation when the display exponent reaches 6.
529  */
530  Assert(nexp < 7);
531  /* gcc only seems to want to optimize memmove for small 2^n */
532  if (nexp & 4)
533  {
534  memmove(result + index - 1, result + index, 4);
535  index += 4;
536  }
537  if (nexp & 2)
538  {
539  memmove(result + index - 1, result + index, 2);
540  index += 2;
541  }
542  if (nexp & 1)
543  {
544  result[index - 1] = result[index];
545  }
546  result[nexp] = '.';
547  index = olength + 1;
548  }
549  else if (exp >= 0)
550  {
551  /* we supplied the trailing zeros earlier, now just set the length. */
552  index = olength + exp;
553  }
554  else
555  {
556  index = olength + (2 - nexp);
557  }
558 
559  return index;
560 }
static void output(uint64 loop_count)
signed int int32
Definition: c.h:355
Definition: type.h:89
char * c
unsigned int uint32
Definition: c.h:367
uint32 mantissa
Definition: f2s.c:217
int32 exponent
Definition: f2s.c:218
#define Assert(condition)
Definition: c.h:738
int i
static const char DIGIT_TABLE[200]
Definition: numutils.c:29

Variable Documentation

◆ FLOAT_POW5_INV_SPLIT

const uint64 FLOAT_POW5_INV_SPLIT[31]
static
Initial value:
= {
UINT64CONST(576460752303423489), UINT64CONST(461168601842738791), UINT64CONST(368934881474191033), UINT64CONST(295147905179352826),
UINT64CONST(472236648286964522), UINT64CONST(377789318629571618), UINT64CONST(302231454903657294), UINT64CONST(483570327845851670),
UINT64CONST(386856262276681336), UINT64CONST(309485009821345069), UINT64CONST(495176015714152110), UINT64CONST(396140812571321688),
UINT64CONST(316912650057057351), UINT64CONST(507060240091291761), UINT64CONST(405648192073033409), UINT64CONST(324518553658426727),
UINT64CONST(519229685853482763), UINT64CONST(415383748682786211), UINT64CONST(332306998946228969), UINT64CONST(531691198313966350),
UINT64CONST(425352958651173080), UINT64CONST(340282366920938464), UINT64CONST(544451787073501542), UINT64CONST(435561429658801234),
UINT64CONST(348449143727040987), UINT64CONST(557518629963265579), UINT64CONST(446014903970612463), UINT64CONST(356811923176489971),
UINT64CONST(570899077082383953), UINT64CONST(456719261665907162), UINT64CONST(365375409332725730)
}

Definition at line 54 of file f2s.c.

Referenced by mulPow5InvDivPow2().

◆ FLOAT_POW5_SPLIT

const uint64 FLOAT_POW5_SPLIT[47]
static
Initial value:
= {
UINT64CONST(1152921504606846976), UINT64CONST(1441151880758558720), UINT64CONST(1801439850948198400), UINT64CONST(2251799813685248000),
UINT64CONST(1407374883553280000), UINT64CONST(1759218604441600000), UINT64CONST(2199023255552000000), UINT64CONST(1374389534720000000),
UINT64CONST(1717986918400000000), UINT64CONST(2147483648000000000), UINT64CONST(1342177280000000000), UINT64CONST(1677721600000000000),
UINT64CONST(2097152000000000000), UINT64CONST(1310720000000000000), UINT64CONST(1638400000000000000), UINT64CONST(2048000000000000000),
UINT64CONST(1280000000000000000), UINT64CONST(1600000000000000000), UINT64CONST(2000000000000000000), UINT64CONST(1250000000000000000),
UINT64CONST(1562500000000000000), UINT64CONST(1953125000000000000), UINT64CONST(1220703125000000000), UINT64CONST(1525878906250000000),
UINT64CONST(1907348632812500000), UINT64CONST(1192092895507812500), UINT64CONST(1490116119384765625), UINT64CONST(1862645149230957031),
UINT64CONST(1164153218269348144), UINT64CONST(1455191522836685180), UINT64CONST(1818989403545856475), UINT64CONST(2273736754432320594),
UINT64CONST(1421085471520200371), UINT64CONST(1776356839400250464), UINT64CONST(2220446049250313080), UINT64CONST(1387778780781445675),
UINT64CONST(1734723475976807094), UINT64CONST(2168404344971008868), UINT64CONST(1355252715606880542), UINT64CONST(1694065894508600678),
UINT64CONST(2117582368135750847), UINT64CONST(1323488980084844279), UINT64CONST(1654361225106055349), UINT64CONST(2067951531382569187),
UINT64CONST(1292469707114105741), UINT64CONST(1615587133892632177), UINT64CONST(2019483917365790221)
}

Definition at line 65 of file f2s.c.

Referenced by mulPow5divPow2().