📄 ftoa_slow.c
字号:
/* Adapted by Richard F. Man, ImageCraft * * fcvt() to support printf * */// check// EFG_convert_B.c for original/* Routines to convert single-precision floating-point values *//* in support of printf() *//* Orginally prepared 2/ 4/00 E.M.Greene *//* Most recent update 2/ 9/00 E.M.Greene */#include <ctype.h>#include <math.h>#include <string.h>#include <stdlib.h>#define OVERFLOW TRUE#define scale_23 (0x800000) /* = pow(2.0, 23.0) */typedef struct { char mantissa_sign; unsigned char scale_bin; char mantissa_BCD[8], exponent_sign, scale_BCD[2];} EFG_data_t;static void EFG_convert(int z, EFG_data_t *dp);static void round_to_n_places(char *vp, int places, signed char *scale){ char *sp; sp = vp + places; *sp += 5; for (;;) { if ((sp < vp) || (*sp <= 9)) break; *sp -= 10; if (sp > vp) (*--sp)++; else { *vp = 1; (*scale)++; } }}static void SP_EFG_convert(long z, EFG_data_t *dp){ char *sp; int n; /* double */ float mantissa, int_digit, e10f, e10; memset(dp, 0, sizeof(EFG_data_t)); if (z != 0) { mantissa = (double)((z & 0xFFFFFFl) | 0x800000l) / scale_23; /* rfm unused if (z < 0) dp->mantissa_sign = '-'; */ dp->scale_bin = ((z >> 23) & 0xFF) - 127;#define LOG10_of_2 0.301030 /* rfm, precompute */ /* log10(2.0) */ e10 = dp->scale_bin * LOG10_of_2; dp->scale_bin = e10; e10f = e10 - dp->scale_bin; mantissa *= exp10(e10f); if (mantissa >= 10.0) { mantissa /= 10; dp->scale_bin++; } else if (mantissa < 1.0) { mantissa *= 10; dp->scale_bin--; } sp = dp->mantissa_BCD; n = 7; do { mantissa = modf(mantissa, &int_digit); *sp++ = int_digit; mantissa *= 10.0; } while (n--); /* rfm unused if ((n = dp->scale_bin) < 0) { n = -n; dp->exponent_sign = '-'; } dp->scale_BCD[0] = n / 10; dp->scale_BCD[1] = n % 10; */ }}char *fcvt(float v, int ndigits, int *dec_scale, int *sign){ int i, n; FI_union_t x; EFG_data_t d; static char sp[8+1]; memset(sp, '\0', 8+1); x.f = v; SP_EFG_convert(x.i, &d); memcpy(sp, d.mantissa_BCD, 8); if (ndigits) { n = ndigits + d.scale_bin+1; if (0 <= n && n <= 7) round_to_n_places(sp, n+1, &d.scale_bin); else n = 7; } else n = 7; /* find the rightmost nonzeroes */ for (; 0 <= n && sp[n] == 0; --n) ; for (i = 0; i <= n; i++) sp[i] += '0'; sp[n+1] = 0; *dec_scale = d.scale_bin + 1; *sign = (x.i < 0); /* what ^%&$&( purpose is served by this???? */ return sp;}/* buf should be at least 8+3=11 bytes long... */void ftoa(float f, int *status) { int scale, sign; char *s, *buf; static char sbuf[11]; *status = 0; if (f == 0.0) { sbuf[0] = '0'; sbuf[1] = '.'; sbuf[2] = '0'; sbuf[3] = 0; return sbuf; } buf = sbuf; s = fcvt(f, 0, &scale, &sign); if (sign) *buf++ = '-'; if (scale <= 0) { *buf++ = '0'; *buf++ = '.'; while (scale) { *buf++ = '0'; scale++; } } else { while (scale) { *buf++ = *s++; scale--; } *buf++ = '.'; } while (*s) *buf++ = *s++; *buf = 0; return sbuf; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -