rscmore testsee738e320 years agoHistory
183 lines · 3.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h> /* * try all combination of flags and float conversions * with some different widths & precisions */ #define Njust 2#define Nplus 3#define Nalt 2#define Nzero 2#define Nspec 5#define Nwidth 5#define Nprec 5 static double fmtvals[] = {	3.1415925535897932e15,	3.1415925535897932e14,	3.1415925535897932e13,	3.1415925535897932e12,	3.1415925535897932e11,	3.1415925535897932e10,	3.1415925535897932e9,	3.1415925535897932e8,	3.1415925535897932e7,	3.1415925535897932e6,	3.1415925535897932e5,	3.1415925535897932e4,	3.1415925535897932e3,	3.1415925535897932e2,	3.1415925535897932e1,	3.1415925535897932e0,	3.1415925535897932e-1,	3.1415925535897932e-2,	3.1415925535897932e-3,	3.1415925535897932e-4,	3.1415925535897932e-5,	3.1415925535897932e-6,	3.1415925535897932e-7,	3.1415925535897932e-8,	3.1415925535897932e-9,	3.1415925535897932e-10,	3.1415925535897932e-11,	3.1415925535897932e-12,	3.1415925535897932e-13,	3.1415925535897932e-14,	3.1415925535897932e-15,}; /* * are the numbers close? * used to compare long numbers where the last few digits are garbage * due to precision problems */static intnumclose(char *num1, char *num2){	int ndig;	double d1, d2;	enum { MAXDIG = 15 }; 	d1 = fmtstrtod(num1, 0);	d2 = fmtstrtod(num2, 0);	if(d1 != d2)		return 0; 	ndig = 0;	while (*num1) {		if (*num1 >= '0' && *num1 <= '9') {			ndig++;			if (ndig > MAXDIG) {				if (!(*num2 >= '0' && *num2 <= '9')) {					return 0;				}			} else if (*num1 != *num2) {				return 0;			}		} else if (*num1 != *num2) {			return 0;		} else if (*num1 == 'e' || *num1 == 'E') {			ndig = 0;		}		num1++;		num2++;	}	if (*num1 || !num2)		return 0;	return 1;} static voiddoit(int just, int plus, int alt, int zero, int width, int prec, int spec){	char format[256];	char *p;	const char *s;	int i; 	p = format;	*p++ = '%';	if (just > 0)		*p++ = "-"[just - 1];	if (plus > 0)		*p++ = "+ "[plus - 1];	if (alt > 0)		*p++ = "#"[alt - 1];	if (zero > 0)		*p++ = "0"[zero - 1]; 	s = "";	switch (width) {	case 1: s = "1"; break;	case 2: s = "5"; break;	case 3: s = "10"; break;	case 4: s = "15"; break;	}	strcpy(p, s); 	s = "";	switch (prec) {	case 1: s = ".0"; break;	case 2: s = ".2"; break;	case 3: s = ".5"; break;	case 4: s = ".15"; break;	}	strcat(p, s); 	p = strchr(p, '\0');	*p++ = "efgEG"[spec];	*p = '\0'; 	for (i = 0; i < sizeof(fmtvals) / sizeof(fmtvals[0]); i++) {		char ref[1024], buf[1024];		Rune rbuf[1024];		double d1, d2; 		sprintf(ref, format, fmtvals[i]);		snprint(buf, sizeof(buf), format, fmtvals[i]);		if (strcmp(ref, buf) != 0		&& !numclose(ref, buf)) {			d1 = fmtstrtod(ref, 0);			d2 = fmtstrtod(buf, 0);			fprintf(stderr, "%s: ref='%s'%s fmt='%s'%s\n", 				format, 				ref, d1==fmtvals[i] ? "" : " (ref is inexact!)", 				buf, d2==fmtvals[i] ? "" : " (fmt is inexact!)");		//	exits("oops");		} 		/* Check again with output to rune string */		runesnprint(rbuf, 1024, format, fmtvals[i]);		snprint(buf, sizeof(buf), "%S", rbuf);		if (strcmp(ref, buf) != 0		&& !numclose(ref, buf)) {			d1 = fmtstrtod(ref, 0);			d2 = fmtstrtod(buf, 0);			fprintf(stderr, "%s: ref='%s'%s fmt='%s'%s\n", 				format, 				ref, d1==fmtvals[i] ? "" : " (ref is inexact!)", 				buf, d2==fmtvals[i] ? "" : " (fmt is inexact!)");		//	exits("oops");		}	}} voidmain(int argc, char **argv){	int just, plus, alt, zero, width, prec, spec; 	for (just = 0; just < Njust; just++)	for (plus = 0; plus < Nplus; plus++)	for (alt = 0; alt < Nalt; alt++)	for (zero = 0; zero < Nzero; zero++)	for (width = 0; width < Nwidth; width++)	for (prec = 0; prec < Nprec; prec++)	for (spec = 0; spec < Nspec; spec++)		doit(just, plus, alt, zero, width, prec, spec); 	exits(0);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t