Rev 195 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 195 | Rev 228 | ||
---|---|---|---|
Line 29... | Line 29... | ||
29 | #include <putchar.h> |
29 | #include <putchar.h> |
30 | #include <print.h> |
30 | #include <print.h> |
31 | #include <synch/spinlock.h> |
31 | #include <synch/spinlock.h> |
32 | #include <arch/arg.h> |
32 | #include <arch/arg.h> |
33 | #include <arch/asm.h> |
33 | #include <arch/asm.h> |
34 | #include <arch.h> |
34 | #include <arch/fmath.h> |
35 | 35 | ||
- | 36 | #include <arch.h> |
|
36 | 37 | ||
37 | static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */ |
38 | static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */ |
38 | static spinlock_t printflock; /**< printf spinlock */ |
39 | static spinlock_t printflock; /**< printf spinlock */ |
39 | 40 | ||
- | 41 | #define DEFAULT_DOUBLE_PRECISION 16 |
|
- | 42 | #define DEFAULT_DOUBLE_BUFFER_SIZE 128 |
|
- | 43 | ||
- | 44 | void print_double(double num, __u16 precision) |
|
- | 45 | { |
|
- | 46 | double intval,intval2; |
|
- | 47 | int counter; |
|
- | 48 | int exponent,exponenttmp; |
|
- | 49 | unsigned char buf[DEFAULT_DOUBLE_BUFFER_SIZE]; |
|
- | 50 | unsigned long in1,in2; |
|
- | 51 | /* |
|
- | 52 | if (fmath_is_nan(num)) { |
|
- | 53 | print_str("NaN"); |
|
- | 54 | return; |
|
- | 55 | } |
|
- | 56 | */ |
|
- | 57 | ||
- | 58 | if (fmath_is_negative(num)) { |
|
- | 59 | putchar('-'); |
|
- | 60 | } |
|
- | 61 | ||
- | 62 | num=fmath_abs(num); |
|
- | 63 | ||
- | 64 | /* |
|
- | 65 | if (fmath_is_infinity(num)) { |
|
- | 66 | print_str("Inf"); |
|
- | 67 | } |
|
- | 68 | */ |
|
- | 69 | //TODO: rounding constant - when we got fraction >= 0.5, we must increment last printed number |
|
- | 70 | ||
- | 71 | /* Here is problem with cumulative error while printing big double values -> we will divide |
|
- | 72 | the number with a power of 10, print new number with better method for small numbers and then print decimal point at correct position */ |
|
- | 73 | ||
- | 74 | fmath_fint(fmath_get_decimal_exponent(num),&intval); |
|
- | 75 | ||
- | 76 | exponent=(intval>0.0?intval:0); |
|
- | 77 | ||
- | 78 | precision+=exponent; |
|
- | 79 | ||
- | 80 | if (exponent>0) num = num / ((fmath_dpow(10.0,exponent))); |
|
- | 81 | ||
- | 82 | num=fmath_fint(num,&intval); |
|
- | 83 | ||
- | 84 | if (precision>0) { |
|
- | 85 | counter=precision-1; |
|
- | 86 | if (exponent>0) counter++; |
|
- | 87 | ||
- | 88 | if (counter>=DEFAULT_DOUBLE_BUFFER_SIZE) { |
|
- | 89 | counter=DEFAULT_DOUBLE_BUFFER_SIZE; |
|
- | 90 | } |
|
- | 91 | exponenttmp=exponent; |
|
- | 92 | while(counter>=0) { |
|
- | 93 | num *= 10.0; |
|
- | 94 | num = fmath_fint(num,&intval2); |
|
- | 95 | buf[counter--]=((int)intval2)+'0'; |
|
- | 96 | exponenttmp--; |
|
- | 97 | if ((exponenttmp==0)&&(counter>=0)) buf[counter--]='.'; |
|
- | 98 | } |
|
- | 99 | counter=precision; |
|
- | 100 | if ((exponent==0)&&(counter<DEFAULT_DOUBLE_BUFFER_SIZE)) buf[counter]='.'; |
|
- | 101 | counter++; |
|
- | 102 | } else { |
|
- | 103 | counter=0; |
|
- | 104 | } |
|
- | 105 | ||
- | 106 | if (intval==0.0) { |
|
- | 107 | if (counter<DEFAULT_DOUBLE_BUFFER_SIZE) buf[counter++]='0'; |
|
- | 108 | } else { |
|
- | 109 | in1=intval; |
|
- | 110 | while(( in1>0 )&&(counter<DEFAULT_DOUBLE_BUFFER_SIZE)) { |
|
- | 111 | ||
- | 112 | in2=in1; |
|
- | 113 | in1/=10; |
|
- | 114 | buf[counter]=in2-in1*10 + '0'; |
|
- | 115 | counter++; |
|
- | 116 | } |
|
- | 117 | } |
|
- | 118 | ||
- | 119 | counter = (counter>=DEFAULT_DOUBLE_BUFFER_SIZE?DEFAULT_DOUBLE_BUFFER_SIZE:counter); |
|
- | 120 | while (counter>0) { |
|
- | 121 | putchar(buf[--counter]); |
|
- | 122 | }; |
|
- | 123 | return; |
|
- | 124 | } |
|
40 | 125 | ||
41 | /** Print NULL terminated string |
126 | /** Print NULL terminated string |
42 | * |
127 | * |
43 | * Print characters from str using putchar() until |
128 | * Print characters from str using putchar() until |
44 | * \x00 character is reached. |
129 | * \x00 character is reached. |
Line 207... | Line 292... | ||
207 | case 'b': |
292 | case 'b': |
208 | print_fixed_hex(va_arg(ap, __native), INT8); |
293 | print_fixed_hex(va_arg(ap, __native), INT8); |
209 | goto loop; |
294 | goto loop; |
210 | 295 | ||
211 | /* |
296 | /* |
- | 297 | * Floating point conversions. |
|
- | 298 | */ |
|
- | 299 | ||
- | 300 | case 'F': |
|
- | 301 | case 'f': |
|
- | 302 | print_double(va_arg(ap, double),DEFAULT_DOUBLE_PRECISION); |
|
- | 303 | goto loop; |
|
- | 304 | /* |
|
212 | * Decimal and hexadecimal conversions. |
305 | * Decimal and hexadecimal conversions. |
213 | */ |
306 | */ |
214 | case 'd': |
307 | case 'd': |
215 | print_number(va_arg(ap, __native), 10); |
308 | print_number(va_arg(ap, __native), 10); |
216 | goto loop; |
309 | goto loop; |