diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/lib/ap/stdio/ftoa.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/lib/ap/stdio/ftoa.c')
-rwxr-xr-x | sys/src/ape/lib/ap/stdio/ftoa.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/sys/src/ape/lib/ap/stdio/ftoa.c b/sys/src/ape/lib/ap/stdio/ftoa.c new file mode 100755 index 000000000..b241d2d43 --- /dev/null +++ b/sys/src/ape/lib/ap/stdio/ftoa.c @@ -0,0 +1,41 @@ +#include <math.h> +#include <stdlib.h> +double pow10(int); +#define NDIG 18 +#define NFTOA (NDIG+4) +/* + * convert floating to ascii. ftoa returns an integer e such that + * f=g*10**e, with .1<=|g|<1 (e=0 when g==0) and puts an ascii + * representation of g in the buffer pointed to by bp. bp[0] will + * be '+' or '-', and bp[1] to bp[NFTOA-2] + * will be appropriate digits of g. bp[NFTOA-1] will be '\0' + */ +int ftoa(double f, char *bp){ + int e, e1, e2, i; + double digit, g, p; + if(f>=0) *bp++='+'; + else{ + f=-f; + *bp++='-'; + } + /* find e such that f==0 or 1<=f*pow10(e)<10, and set f=f*pow10(e) */ + if(f==0.) e=1; + else{ + frexp(f, &e); + e=-e*30103/100000; + /* split in 2 pieces to guard against overflow in extreme cases */ + e1=e/2; + e2=e-e1; + p=f*pow10(e2); + while((g=p*pow10(e1))<1.) e1++; + while((g=p*pow10(e1))>=10.) --e1; + e=e1+e2; + f=g; + } + for(i=0;i!=NDIG;i++){ + f=modf(f, &digit)*10.; + *bp++=digit+'0'; + } + *bp='\0'; + return 1-e; +} |