units.cpp
来自「eC++编译器源码」· C++ 代码 · 共 488 行 · 第 1/2 页
CPP
488 行
if ((right&mask[k])==0L) index[k] = LONG(i);
} else INC(exps[i]);
};
if ((right&LONG(j))!=0L) {
if (i>=MAXTYPES) {
k = TRUNC(typesInUse[i].type);
INC(exps[k], typesInUse[i].exponent-1L);
if ((left&mask[k])==0L) index[k] = LONG(i);
} else INC(exps[i]);
};
INC(j, j);
};
left = 0L;
for (i=0; i<MAXTYPES; i=i+1) {
if (exps[i]>0L) {
left = left|mask[i];
if (exps[i]>1L)
if (index[i]!=0L) left = left|mask[TRUNC(index[i])];
else if (exps[i]>1L) {
left = left|mask[AddTypeExp(LONG(i),exps[i])];
};
};
};
return left;
};
return left|right;
};
// could try to do cancellations first but didn't bother
void divide(UnitFraction &f, long top, long bottom)
{
unsigned int i,j,k;
long exps[MAXTYPES]; //this idea would work for strings too
long index[MAXTYPES];
for (i=0; i<MAXTYPES; i=i+1) {exps[i]=0L; index[i]=0L;};
if ((top&bottom&MAXTYPEMASK)!=0L) {
j = 1;
for (i=0; i<MAXINUSE; i=i+1) {
if ((top&LONG(j))!=0L) {
if (i>=MAXTYPES) {
k = TRUNC(typesInUse[i].type);
INC(exps[k], typesInUse[i].exponent-1L);
if ((bottom&mask[k])==0L) index[k] = LONG(i);
} else INC(exps[i]);
};
if ((bottom&LONG(j))!=0L) {
if (i>=MAXTYPES) {
k = TRUNC(typesInUse[i].type);
DEC(exps[k], typesInUse[i].exponent-1L);
if ((top&mask[k])==0L) index[k] = LONG(i);
} else DEC(exps[i]);
};
INC(j, j);
};
top = 0L; bottom = 0L;
for (i=0; i<MAXTYPES; i=i+1) {
if (exps[i]>0L) {
top = top|mask[i];
if (exps[i]>1L)
if (index[i]!=0L) top = top|mask[TRUNC(index[i])];
else {
top = top |mask[AddTypeExp(LONG(i),exps[i])];
};
} else if (exps[i]<0L) {
bottom = bottom|mask[i];
if (exps[i]<-1L)
if (index[i]!=0L) bottom = bottom|mask[TRUNC(index[i])];
else {
bottom = bottom|mask[AddTypeExp(LONG(i),-exps[i])];
};
};
};
};
f.numerator = top; f.denominator = bottom;
};
boolean Match(long op, /*inout*/ UnitFraction &left, UnitFraction right)
{
long temp;
switch (TRUNC(op)) {
case 0: //+ - etc. types must match
if ((left.numerator==right.numerator) &&
(left.denominator==right.denominator)) return true;
else return false;
case 1: // / invert right operand and multiply
temp = right.numerator;
right.numerator = right.denominator;
right.denominator = temp;
case 2: // * multiply, canceling equal ratios
divide(left, multiply(left.numerator, right.numerator),
multiply(left.denominator, right.denominator));
return true;
default:
return false;
};
};
void print()
{
unsigned int i,j;
for (i=0; i<tagCnt; i=i+1) {
InOut.WriteString(tags[i].name);
for (j=0; j<i; j=j+1) RealInOut.WriteReal(convert[dm(i,j)], 12);
InOut.WriteLn();
};
};
long getExponent(long term)
{
long j;
unsigned int i;
if (term==0L) return 0L;
if ((term&(~MAXTYPEMASK))==0L) return 1L;
j = mask[MAXTYPES];
for (i=MAXTYPES; i<MAXINUSE; i=i+1) {
if ((term&j)!=0L) return typesInUse[i].exponent;
INC(j, j)
};
assert(false);
};
long canonical[MAXINUSE];
void Unitsprintf(UNIT &context[], UnitFraction left, float &leftV, char &s[])
{
unsigned int e,i,j,k;
char t[20], u[60];
long num[MAXTYPES], denom[MAXTYPES];
float temp;
for (i=0; i<MAXTYPES; i=i+1) {num[i]=0L; denom[i]=0L;};
s[0] = '\0';
u[0] = '\0';
leftV = left.value;
if ((left.numerator|left.denominator)==0L) return;
j = 1;
for (i=0; i<MAXINUSE; i=i+1) {
if (i>=MAXTYPES) k=TRUNC(typesInUse[i].type); else k=i;
if ((left.numerator&LONG(j))!=0L) {
e=TRUNC(getExponent(LONG(j)));
if (e>1) DEC(e);
INC(num[k], LONG(e));
} else if ((left.denominator&LONG(j))!=0L) {
e=TRUNC(getExponent(LONG(j)));
if (e>1) DEC(e);
INC(denom[k], LONG(e));
};
INC(j, j);
};
for (i=0; i<MAXTYPES; i=i+1) {
if (num[i]>0L) {
temp = Convert(context[i], UNIT(canonical[i]));
leftV = leftV/MathLib2.PowerI(temp, num[i]);
assert(Name(context[i], t)>0);
String.Insert(s, t, String.last);
if (num[i]>1L) {
j = 0;
assert(FInOut.Write1(" ^%2ld", t, j, num[i])==1);
String.Insert(s,t,String.last);
};
} else if (denom[i]>0L) {
leftV = leftV*MathLib2.PowerI(Convert(context[i], UNIT(canonical[i])), denom[i]);
assert(Name(context[i], t)>0);
String.Insert(u, t,String.last);
if (denom[i]>1L) {
j = 0;
assert(FInOut.Write1(" ^%2ld", t, j, denom[i])==1);
String.Insert(u,t,String.last);
};
};
};
if (u[0]!='\0') {
assert(s[0]!='\0');
String.InsertCS(s, String.last, "/");
String.Insert(s, u, String.last);
};
};
void Canonical(unsigned int oneOfLENGTHetc, char unitName[])
{
canonical[oneOfLENGTHetc] = Tag(unitName);
limits[oneOfLENGTHetc] = tagCnt-1;
};
unsigned int Read(char &s[], unsigned int pos, UnitFraction &f)
{ unsigned int apos, bit;
char ss[20];
UNIT i, current;
apos = pos;
f.numerator = 0L;
if (FInOut.Read1("%f", s, apos, f.value)!=1) return 0;
if (FInOut.Read1("%s", s, apos, ss)!=1) return 0;
for ( ;; ) {
i = Tag(ss);
if (i==NOUNIT) return 0;
for (current=0; current<MAXTYPES; current++) {
if (i<=limits[current]) break;
};
if (current>=MAXTYPES) return 0;
bit=LENGTH;
current = canonical[bit];
f.value = f.value/Convert(current, i);
if (f.numerator&mask[bit]) return 0;
INC(f.numerator, mask[bit]);
if (FInOut.Read1("%s", s, apos, ss)!=1) break;
};
f.denominator = 0L;
return apos-pos;
};
void units()
{ unsigned int i,j;
tagCnt = 0;
for (i=0; i<MAXCONVERT; i=i+1) convert[i]=0.0;
for (i=0; i<MAXTYPES; i++) limits[i] = 0;
for (i=0; i<MAXINUSE; i=i+1) {typesInUse[i].type=0L; typesInUse[i].exponent=0L;};
mask[0] = 1L;
for (i=1; i<31; i=i+1) mask[i] = mask[i-1]*2L;
mask[31] = 0x80000000L;
inuseCnt = 0;
/* Fact("Mils", "Inches", 0.001);
Fact("Fathoms", "Feet", 6.0);
Fact("Rods", "Yards", 5.5);
Fact("Furlongs", "Rods", 40.0);
Fact("Meters", "Decimeters", 10.0);
Fact("Meters", "Centimeters", 100.0);
Fact("Meters", "Millimeters", 1000.0);
Fact("Meters", "Micrometers", 1000000.0);
Fact("Meters", "Nanometers", 1.0E+9);
Fact("Micrometers", "Microns", 1.0);
Fact("Dekameters", "Meters", 10.0);
Fact("Hectometers", "Meters", 100.0);
Fact("Megameters", "Meters", 1000000.0);
Fact("Gigameters", "Meters", 1.0e+9);
Fact("Angstroms", "Centimeters", 10.0E-8);*/
i=AddTypeExp(1L,1L);
i=AddTypeExp(0L,1L);
i=AddTypeExp(2L,1L);
i=AddTypeExp(3L,1L);
i=AddTypeExp(4L,1L);
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?