diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/include/stdio.h | 2 | ||||
| -rw-r--r-- | libc/include/stdlib.h | 5 | ||||
| -rw-r--r-- | libc/stdio.c | 6 | ||||
| -rw-r--r-- | libc/stdlib.c | 62 |
4 files changed, 52 insertions, 23 deletions
diff --git a/libc/include/stdio.h b/libc/include/stdio.h index 92442ac..49966cf 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -3,5 +3,5 @@ int puts(const char*); int putchar(int); /* sets the I/O functions, allows easy switching between text mode and VBE */ -void set_putchar(void (*func)(char)); +void set_putchar(void (*func)(int)); void set_puts(void (*func)(const char*)); diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 0a3d559..91f16f3 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -3,5 +3,8 @@ /* NOT reentrant! */ char* itoa(int val, int base); -int rand(void); +#define RAND_MAX ((1U << 31) - 1) + +unsigned int rand(void); void srand(unsigned int); +int abs(int); diff --git a/libc/stdio.c b/libc/stdio.c index 0ef8b0c..8219d11 100644 --- a/libc/stdio.c +++ b/libc/stdio.c @@ -3,12 +3,12 @@ #include <stdio.h> #include <stdlib.h> -static void (*putchar_ptr)(char) = log_putchar; +static void (*putchar_ptr)(int) = log_putchar; static void (*puts_ptr)(const char*) = log_puts; int putchar(int ch) { - putchar_ptr((char)ch); + putchar_ptr(ch); return 0; } @@ -18,7 +18,7 @@ int puts(const char* str) return 0; } -void set_putchar(void (*func)(char)) +void set_putchar(void (*func)(int)) { putchar_ptr = func; } diff --git a/libc/stdlib.c b/libc/stdlib.c index ca890b4..bea3b65 100644 --- a/libc/stdlib.c +++ b/libc/stdlib.c @@ -5,35 +5,61 @@ char* itoa(int val, int base) { static char buf[32] = {0}; - int i = 30; + int neg = 0; + + if(val < 0) + { + val = -val; + neg = 1; + } - for(; val && i ; --i, val /= base) + int i = 30; + do + { buf[i] = "0123456789abcdef"[val % base]; + --i; + val /= base; + } + while(val && i); + + if(neg) + { + buf[i] = '-'; + } - return &buf[i+1]; + return &buf[i+(neg?0:1)]; } -static int rand_state = 42; +static unsigned long rand_s1 = 18, rand_s2 = 5, rand_s3 = 43; -/* some constants for the RNG */ -#define A 48271 -#define M 2147483647 -#define Q (M/A) -#define R (M%A) +#define M 1103515245UL +#define A 12345UL -int rand(void) +/* this is a very fast tausworthe RNG */ + +unsigned int rand(void) { - int tmp = A * (rand_state % Q) - R * (rand_state / Q); - if(tmp >= 0) - rand_state = tmp; - else - rand_state = tmp + M; - return rand_state; + rand_s1 = (((rand_s1&4294967294)<<12)^(((rand_s1<<13)^rand_s1)>>19)); + rand_s2 = (((rand_s2&4294967288)<< 4)^(((rand_s2<< 2)^rand_s2)>>25)); + rand_s3 = (((rand_s3&4294967280)<<17)^(((rand_s3<< 3)^rand_s3)>>11)); + return (rand_s1 ^ rand_s2 ^ rand_s3); } void srand(unsigned int seed) { - /* prevent a zero seed */ - rand_state = (!seed?42:seed); + if(!seed) + seed = 42; + rand_s1 = seed++; + rand_s2 = seed++; + rand_s3 = seed++; + /* "warm it up" */ + rand(); + rand(); + rand(); +} + +int abs(int val) +{ + return (val<0?-val:val); } |