[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH v2] libc: Doubles in printf



+ libc: printf: Unterstuetzung fuer Ausgabe von (long) doubles

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/modules/lib/stdlibc/jprintf.c |   63 +++++++++++++++++++++++++++++++++++++
 1 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/src/modules/lib/stdlibc/jprintf.c b/src/modules/lib/stdlibc/jprintf.c
index 067d1bd..b451227 100644
--- a/src/modules/lib/stdlibc/jprintf.c
+++ b/src/modules/lib/stdlibc/jprintf.c
@@ -111,6 +111,43 @@ char * ulltoa(unsigned long long value, char * buf, unsigned int radix, unsigned
 
     return buf;
 }
+
+/**
+ * Konvertiert eine Gleitkommazahl in einen String
+ *
+ * @param value Die Zahl
+ * @param buf Der Puffer
+ * @param precision Anzahl der Nachkommastellen
+ *
+ * @return buf
+ */
+static void ldtoa(long double value, char* buf, unsigned int precision)
+{
+    // Negative Zahlen gleich rausfiltern
+    if (value < 0) {
+        *buf++ = '-';
+        value = -value;
+    }
+
+    // Integeranteil ausgeben
+    ulltoa((unsigned long long) value, buf, 10, 0);
+    value -= (unsigned long long) value;
+    buf += strlen(buf);
+
+    // Nachkommastellen
+    if (value && precision) {
+        *buf++ = '.';
+    }
+
+    while (value && precision--) {
+        value *= 10.0;
+        *buf++ = '0' + (int) value;
+        value -= (int) value;
+    }
+
+    *buf = '\0';
+}
+
 
 /**
  * Ruft die dem Kontext entsprechende putc Funktion auf.
@@ -212,6 +249,7 @@ int jvprintf(struct jprintf_args * args, const char * format, va_list ap)
 	unsigned int width;
 	unsigned int precision;
 	unsigned int length;
+    unsigned int long_double;
 	
 	bytes_written = 0;
 
@@ -244,6 +282,7 @@ int jvprintf(struct jprintf_args * args, const char * format, va_list ap)
 		width = 0;
 		precision = -1;
 		length = 32;
+        long_double = 0;
 
 		// flags
 		switch(*format)
@@ -312,6 +351,7 @@ int jvprintf(struct jprintf_args * args, const char * format, va_list ap)
 			break;
 		case 'L':
 			// long double
+            long_double = 1;
 			format++;
 			break;
 		}
@@ -458,6 +498,29 @@ int jvprintf(struct jprintf_args * args, const char * format, va_list ap)
 			}
 			format++;
 			break;
+        case 'f':
+        case 'g':
+            // FIXME Bei g duerfen keine abschliessenden Nullen vorkommen
+            if (precision == -1) {
+                precision = 6;
+            }
+            {
+                // 64-Bit-Integer gehen dezimal in maximal 21 Zeichen, dazu
+                // Vorzeichen, Komma und abschliessendes Nulbyte
+                char buf[precision + 21 + 3];
+                long double value;
+
+                if (long_double) {
+                    value = va_arg(ap, long double);
+                } else {
+                    value = va_arg(ap, double);
+                }
+
+                ldtoa(value, buf, precision);
+                WRITE_STRING(buf, -1);
+            }
+            format++;
+            break;
         case 'c':
             {
 				char c = (char)va_arg(ap, int);
-- 
1.6.0.2