7ada1b22af7c998ef173aa68c62f3acc64dd2cc5
[mw/micromonitor-lm32.git] / umon_main / target / glib / sprnfloat.c
1 #include <ctype.h>
2 #include <float.h>
3 #include <stdlib.h>
4 #include <math.h>
5 #include <string.h>
6
7 extern int long_to_dec(long lval,char *buf,char *bufend,char *hdr);
8
9 typedef union {
10         long L;
11         float F;
12 } LF_t;
13
14 char *
15 sprnfloat(char *buf, int bsize, float fpval, int trunc)
16 {
17         LF_t    lf;
18         char    *bp;
19         short   exp2;
20         long    mantissa, int_part, frac_part;
21
22         if (fpval == 0.0) {
23                 strcpy(buf, "0.0");
24                 return buf;
25         }
26         lf.F = fpval;
27
28         exp2 = (0xFF & (lf.L >> 23)) - 127;
29         mantissa = (lf.L & 0xFFFFFF) | 0x800000;
30         frac_part = 0;
31         int_part = 0;
32
33         if (exp2 >= 31) {
34                 strcpy(buf, "FPTOOBIG");
35                 return(buf);
36         }else if (exp2 < -23) {
37                 strcpy(buf, "FPTOOSMALL");
38                 return(buf);
39         }else if (exp2 >= 23)
40                 int_part = mantissa << (exp2 - 23);
41         else if (exp2 >= 0) {
42                 int_part = mantissa >> (23 - exp2);
43                 frac_part = (mantissa << (exp2 + 1)) & 0xFFFFFF;
44         }else /* if (exp2 < 0) */
45                 frac_part = (mantissa & 0xFFFFFF) >> -(exp2 + 1);
46
47         bp = buf;
48
49         if (lf.L < 0)
50                 *bp++ = '-';
51
52         if (int_part == 0)
53                 *bp++ = '0';
54         else
55                 bp += long_to_dec(int_part,bp,buf+bsize-1,"");
56         *bp++ = '.';
57
58         if (frac_part == 0)
59                 *bp++ = '0';
60         else {
61                 char m, max;
62
63                 max = bsize - (bp - buf) - 1;
64                 if (max > trunc)
65                         max = trunc;
66                 /* print BCD */
67                 for (m = 0; m < max; m++) {
68                         /* frac_part *= 10; */
69                         frac_part = (frac_part << 3) + (frac_part << 1);
70
71                         *bp++ = (frac_part >> 24) + '0';
72                         frac_part &= 0xFFFFFF;
73                 }
74                 /* delete ending zeroes */
75                 for (--bp; bp[0] == '0' && bp[-1] != '.'; --bp)
76                         ;
77                 ++bp;
78         }
79         *bp = 0;
80
81         return(buf);
82 }