2013年12月15日日曜日

32bit整数レジスタを自己流実数レジスタとして扱い四則演算を行う

自己流実数レジスタの範囲は -2047.9999〜+2047.99999
有効なのは小数点以下5けたくらいまで


akira@dynabookAZ:~/arm1312$ ./c005
Number: .2
l=33333
Number: -3
l=80300000
@@@  add  @@@   l=802ccccd   -2.8000001907
@@@  sub  @@@   l=  333333   +3.1999998092
@@@  mul  @@@   l=80099999   -0.5999994277
@@@  div  @@@   l=80011111   -0.0666666030
akira@dynabookAZ:~/arm1312$ ./c005
Number: -1.2
l=80133333
Number: -.6
l=80099999
@@@  add  @@@   l=801ccccc   -1.7999992370
@@@  sub  @@@   l=8009999a   -0.6000003814
@@@  mul  @@@   l=   b851d   +0.7199983596
@@@  div  @@@   l=  200001   +2.0000009536
akira@dynabookAZ:~/arm1312$ ./c005
Number: -.5
l=80080000
Number: .7
l=b3333
@@@  add  @@@   l=   33333   +0.1999998092
@@@  sub  @@@   l=80133333   -1.1999998092
@@@  mul  @@@   l=80059999   -0.3499994277
@@@  div  @@@   l=800b6db7   -0.7142858505
akira@dynabookAZ:~/arm1312$ ./c005
Number: 2.2
l=233333
Number: 3.3
l=34cccc
@@@  add  @@@   l=  57ffff   +5.4999990463
@@@  sub  @@@   l=80119999   -1.0999994277
@@@  mul  @@@   l=  7428f3   +7.2599973678
@@@  div  @@@   l=   aaaaa   +0.6666660308
akira@dynabookAZ:~/arm1312$ cat c005.c
#include <stdio.h>
#include <stdlib.h>
#define  x8  0x80000000
#define  x7f 0x7fffffff

long main1();
long add0(long l1,long l2);
long sub0(long l1,long l2);
long add1(long l1,long l2);
long sub1(long l1,long l2);
long mul1(long l1,long l2);
long div1(long l1,long l2);
void printl(char *txt,long l);

main(){
   long l,l1,l2;
   l1=main1();
   l2=main1();
   l=add1(l1,l2);
   printl("add",l);
   l=sub1(l1,l2);
   printl("sub",l);
   l=mul1(l1,l2);
   printl("mul",l);
   l=div1(l1,l2);
   printl("div",l);
}

long add0(long l1,long l2){
   return (l1+l2);
}

long sub0(long l1,long l2){
   if(l1>=l2) return (l1-l2);
   else       return ((l2-l1)^x8);
}

long add1(long l1,long l2){
   long s1,s2;

   s1=l1&x8;
   s2=l2&x8;
   l1&=x7f;
   l2&=x7f;
   if(s1!=x8&&s2!=x8) return add0(l1,l2);
   if(s1!=x8&&s2==x8) return sub0(l1,l2);
   if(s1==x8&&s2!=x8) return sub0(l1,l2)^x8;
   if(s1==x8&&s2==x8) return add0(l1,l2)^x8;
}


long sub1(long l1,long l2){
   long s1,s2;

   s1=l1&x8;
   s2=l2&x8;
   l1&=x7f;
   l2&=x7f;
   if(s1!=x8&&s2!=x8) return sub0(l1,l2);
   if(s1!=x8&&s2==x8) return add0(l1,l2);
   if(s1==x8&&s2!=x8) return add0(l1,l2)^x8;
   if(s1==x8&&s2==x8) return sub0(l1,l2)^x8;
}


long mul1(long l1,long l2){
   long long int ll;
   long s1,s2;

   s1=l1&x8;
   s2=l2&x8;
   l1&=x7f;
   l2&=x7f;
   ll=((long long int)l1*l2)>>20;
   return ((long)ll)^(s1^s2);
}

long div1(long l1,long l2){
   long long int ll;
   long s1,s2;

   s1=l1&x8;
   s2=l2&x8;
   l1&=x7f;
   l2&=x7f;
   ll=(((long long int)l1)<<20)/l2;
   return ((long)ll)^(s1^s2);
}


long main1(){
   char ss[100]="                            ";
   long l,l2;
   int  i,kd=0,ke=0,js=0,dotf=0;
   double kf=0.0,kg=0.1,l1;

   printf("Number: ");
   scanf("%s",ss);

   i=0;
   while(ss[i]!='\0'){
      if(ss[i]=='-') js=1;
      if(ss[i]=='.') dotf=1;
      if('0'<=ss[i]&&ss[i]<='9'){
         if(dotf==0){
            kd=ke*10+(ss[i]-48);
            ke=kd;
         }
         else{
            kf+=kg*(ss[i]-48);
            kg*=0.1;
         }
      }
      i++;
   }
   if(kd>=2048){
      printf("2048 OVER !\n");
      exit(0);
   }
   l=kd<<20;
   l1=kf*16.0;
   l2=(int)l1;
   l+=l2<<16;
   l1=(l1-l2)*16.0;
   l2=(int)l1;
   l+=l2<<12;
   l1=(l1-l2)*16.0;
   l2=(int)l1;
   l+=l2<<8;
   l1=(l1-l2)*16.0;
   l2=(int)l1;
   l+=l2<<4;
   l1=(l1-l2)*16.0;
   l2=(int)l1;
   l+=l2;
   if(js==1) l^=x8;
   printf("l=%lx\n",l);
   /*printf("a=%d %ld\n",kd,(long)1<<20);*/
   return l;
}

void printl(char *txt,long l){
   long i,j;
   int  a,dotf=0;

   printf("@@@  %s  @@@   ",txt);
   printf("l=%8lx   ",l);
   if(l<0){ dotf=1; l^=x8; }
   /*printf("%+5ld.",l);*/
   i=l>>20;
   if(dotf==1) printf("-");
   else        printf("+");
   printf("%ld.",i);
   a=0;
   while(a<10){
      i=l&0x000fffff;
      j=((i<<2)+i)<<1;
      l=j;
      j>>=20;
      printf("%lx",j);
      a++;
   }
   printf("\n");
}


akira@dynabookAZ:~/arm1312$

0 件のコメント:

コメントを投稿