root/trunk/units/unit.d

Revision 515, 5.8 kB (checked in by BCS, 5 years ago)

added some values, units, types and operators/function

Line 
1 module unit;
2
3 private import std.math;
4
5 import rational;
6
7 struct Unit(
8             int LengthN,  int LengthD,
9             int MassN,    int MassD,
10             int TimeN,    int TimeD,
11             int TempN,    int TempD,
12             int CurrentN, int CurrentD
13             )
14 {
15     void _rawSet(real v){value = v;}
16     real _rawGet(){return value;}
17
18     static const LenN = LengthN,  LenD = LengthD;
19     static const MasN = MassN,    MasD = MassD;
20     static const TimN = TimeN,    TimD = TimeD;
21     static const TmpN = TempN,    TmpD = TempD;
22     static const CurN = CurrentN, CurD = CurrentD;
23    
24     static assert (Reduce!(LengthN,  LengthD).Reduced, "Length must be in reduced form");
25     static assert (Reduce!(MassN,    MassD).Reduced,   "Mass must be in reduced form");
26     static assert (Reduce!(TimeN,    TimeD).Reduced,   "Time must be in reduced form");
27     static assert (Reduce!(TempN,    TempD).Reduced,   "Temp must be in reduced form");
28     static assert (Reduce!(CurrentN, CurrentD).Reduced,"Current must be in reduced form");
29
30     private real value;
31
32     private alias Unit!(LengthN, LengthD, MassN, MassD, TimeN, TimeD, TempN, TempD, CurrentN, CurrentD) This;
33
34     private template Mul(T)
35     {
36         static if(is(T : real))
37             alias This Mul;
38         else
39             alias Unit!
40                     (
41                         Reduce!(LengthN*T.LenD  + LengthD*T.LenN,  LengthD * T.LenD).V,
42                         Reduce!(MassN*T.MasD    + MassD*T.MasN,    MassD*T.MasD).V,
43                         Reduce!(TimeN*T.TimD    + TimeD*T.TimN,    TimeD*T.TimD).V,
44                         Reduce!(TempN*T.TmpD    + TempD*T.TmpN,    TempD*T.TmpD).V,
45                         Reduce!(CurrentN*T.CurD + CurrentD*T.CurN, CurrentD*T.CurD).V
46                     ) Mul;
47     }
48     public template Div(T)
49     {
50         static if(is(T : real))
51             alias This Div;
52         else
53             alias Unit!
54                     (
55                         Reduce!(LengthN*T.LenD  - LengthD*T.LenN,  LengthD * T.LenD).V,
56                         Reduce!(MassN*T.MasD    - MassD*T.MasN,    MassD*T.MasD).V,
57                         Reduce!(TimeN*T.TimD    - TimeD*T.TimN,    TimeD*T.TimD).V,
58                         Reduce!(TempN*T.TmpD    - TempD*T.TmpN,    TempD*T.TmpD).V,
59                         Reduce!(CurrentN*T.CurD - CurrentD*T.CurN, CurrentD*T.CurD).V
60                     ) Div;
61     }
62
63     static public template RootT(int i)
64     {
65         alias Unit!(
66             Reduce!(LenN, LenD*i).V,
67             Reduce!(MasN, MasD*i).V,
68             Reduce!(TimN, TimD*i).V,
69             Reduce!(TmpN, TmpD*i).V,
70             Reduce!(CurN, CurD*i).V
71             ) RootT;
72     }
73
74     public template Power(int i)
75     {
76         alias Unit!(
77             Reduce!(LenN*i, LenD).V,
78             Reduce!(MasN*i, MasD).V,
79             Reduce!(TimN*i, TimD).V,
80             Reduce!(TmpN*i, TmpD).V,
81             Reduce!(CurN*i, CurD).V
82             ) Power;
83     }
84
85     This opCall(This ret) { return ret; }
86
87     This opNeg() { This ret; ret.value = - this.value; return ret; }
88     This opPos() { return *this; }
89
90     This opAdd(This that) { This ret; ret.value = this.value + that.value; return ret; }
91     This opSub(This that) { This ret; ret.value = this.value - that.value; return ret; }
92     This opAddAssign(This that) { this.value += that.value; return *this; }
93     This opSubAssign(This that) { this.value -= that.value; return *this; }
94
95     int opCmp(This that)
96     {
97         if(this.value < that.value) return -1;
98         if(this.value > that.value) return +1;
99         return 0;
100     }
101
102     int opCmp(real that)
103     {
104         if(this.value < that) return -1;
105         if(this.value > that) return +1;
106         return 0;
107     }
108
109     static if(LengthN == 0 && MassN == 0 && TimeN == 0 && TempN == 0 && CurrentN == 0)
110     {
111         static This opCall(real v) { This ret; ret.value = v; return ret; }
112
113         This opAdd(real that) { This ret; ret.value = this.value + that; return ret; }
114         This opSub(real that) { This ret; ret.value = this.value - that; return ret; }
115         This opAddAssign(real that) { this.value += that; return *this; }
116         This opSubAssign(real that) { this.value -= that; return *this; }
117         This opAdd_r(real that) { This ret; ret.value = that + this.value; return ret; }
118         This opSub_r(real that) { This ret; ret.value = that - this.value; return ret; }
119         real opCast() { return value; }
120
121         This exp()
122         {
123             This ret;
124             ret.value = std.math.exp(this.value);
125             return ret;
126         }
127         This log()
128         {
129             This ret;
130             ret.value = std.math.log(this.value);
131             return ret;
132         }
133         This pow(real p)
134         {
135             This ret;
136             ret.value = std.math.pow(this.value,p);
137             return ret;
138         }
139     }
140    
141     bool Near(This that, int count = 5)
142     {
143         return std.math.feqrel!(real)(this.value,that.value) + count >= real.mant_dig;
144     }
145
146     //static if(is(This == Unit!(1,1, 0,1, 0,1, 0,1, 0,1))) pragma(msg, Mul!(Unit!(1,1, 0,1, 0,1, 0,1, 0,1)).stringof);
147    
148     Mul!(T) opMul(T)(T that) { Mul!(T) ret; static if(is(T : real)) ret.value = this.value * that; else ret.value = this.value * that.value; return ret; }
149     Div!(T) opDiv(T)(T that) { Div!(T) ret; static if(is(T : real)) ret.value = this.value / that; else ret.value = this.value / that.value; return ret; }
150
151     This opMulAssign(real r) { this.value *= r; return *this; }
152     This opDivAssign(real r) { this.value /= r; return *this; }
153    
154     This opMul_r(real that) { This ret; ret.value = this.value * that; return ret; }
155     Power!(-1) opDiv_r(real that) { Power!(-1) ret; ret.value = that / this.value; return ret; }
156    
157     RootT!(i) Root(int i)(){RootT!(i) ret; ret.value = std.math.sqrt(this.value); return ret;}
158     Power!(i) Pow(int i)(){Power!(i) ret; ret.value = std.math.pow(this.value,i); return ret;}
159     This Abs() { This ret; ret.value = std.math.abs(this.value); return ret; } 
160 }
161
162 template Product(T1, T...)
163 {
164     static if(T.length == 0)
165         alias T1 Product;
166     else
167         alias T1.Mul!(Product!(T)) Product;
168 }
169
170 unittest
171 {
172     Unit!(1,1, 0,1, 0,1, 0,1, 0,1) v;  //pragma(msg,"v:\t"~typeof(v).stringof);
173
174     auto v2 = v * v;  //pragma(msg,"v2:\t"~typeof(v2).stringof);
175     auto v3 = v2 / v; //pragma(msg,"v3:\t"~typeof(v3).stringof);
176     auto v4 = v / v;  //pragma(msg,"v4:\t"~typeof(v4).stringof);
177     auto v5 = v4 / v; //pragma(msg,"v5:\t"~typeof(v5).stringof);
178     //auto v6a = v2 + v;
179     auto v6b = v3 + v;
180     auto v7 = v.Root!(2)(); //pragma(msg,"v7:\t"~typeof(v7).stringof);
181     auto v8 = v7.Pow!(4)(); //pragma(msg,"v8:\t"~typeof(v8).stringof);
182 }
Note: See TracBrowser for help on using the browser.