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 + -
显示快捷键?