root/trunk/meta/feqtest.d

Revision 254, 3.5 kB (checked in by pragma, 6 years ago)

--

Line 
1 module meta.feqtest;
2
3 import meta.math;
4 import meta.conv;
5 import std.stdio;
6 import std.math;
7 import meta.ctype;
8
9 template extractExponent(char [] s)
10 {
11     const int extractExponent = parseExponent!(s[parseMantissaConsumed!(s)..$]);
12 }
13
14 static assert(extractExponent!("3.34e467") == 467);
15
16 //   bool feq!(constant real x)(variable real y)
17 //
18 // Return true if and only if the real variable y is equal to the constant x,
19 // to the number of decimal places specified in x.
20 //  Example:  feq!("3.180")(3.1796)  is true, but
21 //            feq!("3.1800")(3.1796) is false.
22
23 template feq(char [] x)
24 {
25     bool feq(real y) {
26         return fabs(y-atof!(x)) < 0.5L * meta.math.pow!(10.0L, extractExponent!(x)-decimalplaces!(x));
27     }
28 }
29
30
31 //-------------------------------------------------------------------
32 //  dprintf() -- typesafe printf, with compile-time
33 //               checking of the format string.
34 //-------------------------------------------------------------------
35
36 // of the form "%s"
37 template str2type(char ch)
38 {
39     static if (ch=='s')         alias char [] str2type;
40     else static if (ch == 'c') alias char str2type;
41     else static if (ch == 'd') alias int str2type;
42     else static if (ch == 'f' || ch=='e' || ch=='g' || ch == 'F' || ch=='E' || ch=='G' || ch=='a' || ch =='A')
43         alias double str2type;
44     else {
45         pragma(msg, "Unrecognised type character '"~ ch ~ "' in dprintf");
46         static assert(0);
47     }
48 }
49
50 // Constructs a string made up of each char that follows each % sign.
51 template getFormatChars(char [] str, bool gotpercent=false)
52 {
53     static if (str.length==0){
54         static if (gotpercent) {
55             pragma(msg, "Error in format string");
56             static assert(0);
57         } else const char [] getFormatChars = "";
58   } else static if (!gotpercent && str[0]=='%') {
59      const char [] getFormatChars = getFormatChars!(str[1..$], true); 
60   } else static if (gotpercent && (str[0]=='.' || str[0]=='-' || str[0]=='+' || isdigit!( (str[0]) ) ) ) {
61      const char [] getFormatChars = getFormatChars!(str[1..$], true);
62   } else static if (gotpercent) {
63       const char [] getFormatChars = str[0] ~ getFormatChars!(str[1..$], false);
64   } else
65       const char [] getFormatChars = getFormatChars!(str[1..$], false);
66 }
67
68 template dprintfT(char [] fstr, char [] str)
69 {
70     static if ( fstr.length==0)
71         void dprintfT() {
72             printf(str);
73         }
74     else static if ( fstr.length==1)
75         void dprintfT(str2type!((fstr[0])) p1) {
76             printf(str, p1);
77         }
78     else static if (fstr.length==2)
79         void dprintfT(str2type!((fstr[0])) p1, str2type!((fstr[1])) p2) {
80             printf(str, p1, p2);
81         }       
82     else {
83       pragma(msg, "Too many parameters in dprintf!");
84       // (but it's trivial to add more)
85       static assert(0);
86     }
87 }
88
89 // Just a demo to show we can manipulate the string.
90 template dprintfln(char [] x)
91 {
92    alias dprintfT!(getFormatChars!(x), x~"\n") dprintfln;
93 }
94
95
96 void main()
97 {
98     real x = 3.1796;
99     if ( feq!("3.180")(x) ) {
100         writefln("equal");
101     } else writefln("not eq");
102
103     assert(  feq!("32.180")(32.1804) );
104     assert( !feq!("32.180")(32.1806) );
105     assert( feq!("-32.180e45")(-3.21803e46) );
106     assert( feq!("-32.180e45")(-3.218049999e46) );
107     assert( feq!("-1e-20")(-9.5e-21) );
108    
109    
110     int q=3;
111     double z = 3.1415;
112     dprintfln!("This is q=%d")(q);
113     dprintfln!("%d")(7);
114     dprintfln!("This is a float %+2.7E and an int %d")(z, q);   
115 }
Note: See TracBrowser for help on using the browser.