summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/stdio/ftoa.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/ape/lib/ap/stdio/ftoa.c41
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;
+}