int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2) { #if 1 union { unsigned long long l; double d; } u = { .d=d }; /* step 1: extract sign, mantissa and exponent */ signed long e=((u.l>>52)&((1<<11)-1))-1023; #else #if __BYTE_ORDER == __LITTLE_ENDIAN signed long e=(((((unsigned long*)&d)[1])>>20)&((1<<11)-1))-1023; #else signed long e=(((*((unsigned long*)&d))>>20)&((1<<11)-1))-1023; #endif #endif /* unsigned long long m=u.l & ((1ull<<52)-1); */ /* step 2: exponent is base 2, compute exponent for base 10 */ signed long e10; /* step 3: calculate 10^e10 */ unsigned int i; double backup=d; double tmp; char *oldbuf=buf; if ((i=isinf(d))) return copystring(buf,maxlen,i>0?"inf":"-inf"); if (isnan(d)) return copystring(buf,maxlen,"nan"); e10=1+(long)(e*0.30102999566398119802); /* log10(2) */ /* Wir iterieren von Links bis wir bei 0 sind oder maxlen erreicht * ist. Wenn maxlen erreicht ist, machen wir das nochmal in * scientific notation. Wenn dann von prec noch was übrig ist, geben * wir einen Dezimalpunkt aus und geben prec2 Nachkommastellen aus. * Wenn prec2 Null ist, geben wir so viel Stellen aus, wie von prec * noch übrig ist. */ if (d==0.0) { prec2=prec2==0?1:prec2+2; prec2=prec2>maxlen?8:prec2; i=0; if (prec2 && (long long)u.l<0) { buf[0]='-'; ++i; } for (; i<prec2; ++i) buf[i]='0'; buf[buf[0]=='0'?1:2]='.'; buf[i]=0; return i; } if (d < 0.0) { d=-d; *buf='-'; --maxlen; ++buf; } /* Perform rounding. It needs to be done before we generate any digits as the carry could propagate through the whole number. */ tmp = 0.5; for (i = 0; i < prec2; i++) { tmp *= 0.1; } d += tmp; if (d < 1.0) { *buf='0'; --maxlen; ++buf; } /* printf("e=%d e10=%d prec=%d\n",e,e10,prec); */ if (e10>0) { int first=1; /* are we about to write the first digit? */ tmp = 10.0; i=e10; while (i>10) { tmp=tmp*1e10; i-=10; } while (i>1) { tmp=tmp*10; --i; } /* the number is greater than 1. Iterate through digits before the * decimal point until we reach the decimal point or maxlen is * reached (in which case we switch to scientific notation). */ while (tmp>0.9) { char digit; double fraction=d/tmp; digit=(int)(fraction); /* floor() */ if (!first || digit) { first=0; *buf=digit+'0'; ++buf; if (!maxlen) { /* use scientific notation */ int len=__dtostr(backup/tmp,oldbuf,maxlen,prec,prec2); int initial=1; if (len==0) return 0; maxlen-=len; buf+=len; if (maxlen>0) { *buf='e'; ++buf; } --maxlen; for (len=1000; len>0; len/=10) { if (e10>=len || !initial) { if (maxlen>0) { *buf=(e10/len)+'0'; ++buf; } --maxlen; initial=0; e10=e10%len; } } if (maxlen>0) goto fini; return 0; } d-=digit*tmp; --maxlen; } tmp/=10.0; } } else { tmp = 0.1; } if (buf==oldbuf) { if (!maxlen) return 0; --maxlen; *buf='0'; ++buf; } if (prec2 || prec>(unsigned int)(buf-oldbuf)+1) { /* more digits wanted */ if (!maxlen) return 0; --maxlen; *buf='.'; ++buf; prec-=buf-oldbuf-1; if (prec2) prec=prec2; if (prec>maxlen) return 0; while (prec>0) { char digit; double fraction=d/tmp; digit=(int)(fraction); /* floor() */ *buf=digit+'0'; ++buf; d-=digit*tmp; tmp/=10.0; --prec; } } fini: *buf=0; return buf-oldbuf; }
int main(int argc,char *argv[]) { int i; for (i=0; i<1024; ++i) { printf("%08x%c",arc4random(),(i&15)==15 ? '\n' : ' '); } perror("write"); #if 0 int n; struct ucontext uc; n=0; getcontext(&uc); puts("getcontext returned"); if (n==0) { ++n; setcontext(&uc); puts("should not get here"); exit(1); } puts("all ok"); return 0; #endif #if 0 char* a=malloc(-3); char* b=malloc(0xffffffffull+1); printf("%p %p\n",a,b); #endif #if 0 printf("%u\n",getpagesize()); #endif #if 0 struct stat s; time_t t=time(0); struct tm* T; stat("/tmp/nyt.html",&s); T=gmtime(&s.st_mtime); #endif #if 0 static struct mq_attr x; mqd_t a=mq_open("fnord",O_WRONLY|O_CREAT,0600,&x); mqd_t b=mq_open("fnord",O_RDONLY); #endif #if 0 struct statfs s; if (statfs("/tmp",&s)!=-1) { printf("%llu blocks, %llu free\n",(unsigned long long)s.f_blocks,(unsigned long long)s.f_bfree); } #endif #if 0 char* c=strndupa("fnord",3); puts(c); #endif #if 0 char buf[100]; __write2("foo!\n"); memset(buf,0,200); #endif #if 0 printf("%+05d\n",500); #endif #if 0 char* c; printf("%d\n",asprintf(&c,"foo %d",23)); puts(c); #endif #if 0 struct winsize ws; if (!ioctl(0, TIOCGWINSZ, &ws)) { printf("%dx%d\n",ws.ws_col,ws.ws_row); } #endif #if 0 struct termios t; if (tcgetattr(1,&t)) { puts("tcgetattr failed!"); return 1; } printf("%d\n",cfgetospeed(&t)); #endif #if 0 printf("%p\n",malloc(0)); #endif #if 0 char* argv[]= {"sh","-i",0}; char buf[PATH_MAX+100]; int i; for (i=0; i<PATH_MAX+20; ++i) buf[i]='a'; memmove(buf,"PATH=/",6); strcpy(buf+i,"/bin:/bin"); putenv(buf); execvp("sh",argv); printf("%d\n",islower(0xfc)); #endif #if 0 char buf[101]; __dtostr(-123456789.456,buf,100,6,2); puts(buf); return 0; #endif #if 0 time_t t=1009921588; puts(asctime(localtime(&t))); #endif #if 0 printf("%g\n",atof("30")); #endif #if 0 char* buf[]= {"FOO=FNORD","A=B","C=D","PATH=/usr/bin:/bin",0}; environ=buf; putenv("FOO=BAR"); putenv("FOO=BAZ"); putenv("BLUB=DUH"); system("printenv"); #endif #if 0 char buf[1024]; time_t t1=time(0); struct tm* t=localtime(&t1); printf("%d %s\n",strftime(buf,sizeof buf,"%b %d %H:%M",t),buf); #endif #if 0 tzset(); printf("%d\n",daylight); #endif #if 0 struct in_addr addr; inet_aton("10.0.0.100\t",&addr); printf("%s\n",inet_ntoa(addr)); #endif #if 0 printf("%u\n",getuid32()); #endif #if 0 FILE *f; int i; char addr6p[8][5]; int plen, scope, dad_status, if_idx; char addr6[40], devname[20]; if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { while ((i=fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope, &dad_status, devname)) != EOF) { printf("i=%d\n",i); } } #endif #if 0 printf("%s\n",crypt("test","$1$")); #endif #if 0 MD5_CTX x; unsigned char md5[16]; MD5Init(&x); MD5Update(&x,"a",1); MD5Final(md5,&x); { int i; for (i=0; i<16; ++i) { printf("%02x",md5[i]); } putchar('\n'); } #endif #if 0 long a,b,c; char buf[20]="fnord"; strcpy(buf,"Fnordhausen"); strcpy2(buf,"Fnordhausen"); rdtscl(a); strcpy(buf,"Fnordhausen"); rdtscl(b); strcpy2(buf,"Fnordhausen"); rdtscl(c); printf("C: %d ticks, asm: %d ticks\n",b-a,c-b); #endif /* printf("%d\n",strcmp(buf,"fnord")); */ #if 0 regex_t r; // printf("regcomp %d\n",regcomp(&r,"^(re([\\[0-9\\]+])*|aw):[ \t]*",REG_EXTENDED)); printf("regcomp %d\n",regcomp(&r,"^([A-Za-z ]+>|[]>:|}-][]>:|}-]*)",REG_EXTENDED)); printf("regexec %d\n",regexec(&r,"Marketing-Laufbahn hinterdir.",1,0,REG_NOSUB)); #endif #if 0 FILE *f=fopen("/home/leitner/Mail/outbox","r"); char buf[1024]; int i=0; if (f) { while (fgets(buf,1023,f)) { ++i; printf("%d %lu %s",i,ftell(f),buf); } } #endif #if 0 char template[]="/tmp/duh/fnord-XXXXXX";