2014年3月23日日曜日

ARMのgccでインラインアセンブラをするとき、変数を代入するやり方

akira@dynabookAZ:~/arm1403$ cat add1.c
#include <stdio.h>

int fadd(int x,int y);

main(){
   int a,b,c;
   a=fadd(3,5);
   printf("a=%d\n",a);

}


int fadd(int x,int y){
   int ret;
   ret=x+y;
   return ret;
}


akira@dynabookAZ:~/arm1403$ gcc -o add1 add1.c
akira@dynabookAZ:~/arm1403$ ./add1
a=8
akira@dynabookAZ:~/arm1403$ cat add2.c
#include <stdio.h>

int fadd(int x,int y);

main(){
   int a,b,c;
   a=fadd(13,25);
   printf("a=%d\n",a);

}


int fadd(int x,int y){
   int ret;
   asm("ldr r1,%0"::"g"(x));
   asm("ldr r2,%0"::"g"(y));
   asm("add r1,r1,r2");
   asm("mov %0,r1":"=g"(ret));
   return ret;
}


akira@dynabookAZ:~/arm1403$ gcc -o add2 add2.c
akira@dynabookAZ:~/arm1403$ ./add2
a=38
akira@dynabookAZ:~/arm1403$

2013年12月22日日曜日

32bitの素因数分解のアセンブラプログラム(dynabook AZ)

akira@dynabookAZ:~/arm1312$ ./d003
Favorite Number: 2147483626
2147483626=2*19*37*1527371
2147483627=47*53*862097
2147483628=2*2*3*3*59652323
2147483629=Kake Over
2147483630=2*5*6553*32771
2147483631=3*137*263*19867
2147483632=2*2*2*2*7*73*262657
2147483633=5843*367531
2147483634=2*3*12097*29587
2147483635=5*11*337*115861
2147483636=2*2*536870909
2147483637=3*3*3*13*6118187
2147483638=2*2969*361651
2147483639=7*17*18046081
2147483640=2*2*2*3*5*29*43*113*127
2147483641=2699*795659
akira@dynabookAZ:~/arm1312$ g d003
akira@dynabookAZ:~/arm1312$ ./d003
Favorite Number: 2147483627
2147483627=47*53*862097
2147483628=2*2*3*3*59652323
2147483629=Kake Over
2147483630=2*5*6553*32771
2147483631=3*137*263*19867
2147483632=2*2*2*2*7*73*262657
2147483633=5843*367531
2147483634=2*3*12097*29587
2147483635=5*11*337*115861
2147483636=2*2*536870909
2147483637=3*3*3*13*6118187
2147483638=2*2969*361651
2147483639=7*17*18046081
2147483640=2*2*2*3*5*29*43*113*127
2147483641=2699*795659
2147483642=2*23*46684427
akira@dynabookAZ:~/arm1312$ ./d003
Favorite Number: 2147483640
2147483640=2*2*2*3*5*29*43*113*127
2147483641=2699*795659
2147483642=2*23*46684427
2147483643=3*715827881
2147483644=2*2*233*1103*2089
2147483645=5*19*22605091
2147483646=2*3*3*7*11*31*151*331
Number Over
akira@dynabookAZ:~/arm1312$ ./d003
Favorite Number: 6
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5
11=11
12=2*2*3
13=13
14=2*7
15=3*5
16=2*2*2*2
17=17
18=2*3*3
19=19
20=2*2*5
21=3*7
akira@dynabookAZ:~/arm1312$ cat d003.c
#include <stdio.h>

main(){
   long a,b,c,m,s,i,e,f,g;
   char s1[20]="%s";
   char s2[20]="Favorite Number: ";
   char s3[20]="%ld\n";
   char s4[20]="%ld*";
   char s5[20]="%ld=";
   char s6[20]="%ld";
   char s7[20]="Kake Over\n";
   char s8[20]="Number Over\n";
   char s9[20]="test1\n";
   char s10[20]="test2\n";
/*
   a=1;
   b=2;
   c=3;
   m=4;
   s=5;
   i=6;
   e=7;
   f=8;
   g=9;
*//*
   s1[0]='%';
   s2[0]='F';

   s3[0]='%';
   s4[0]='F';
   s5[0]='%';
   s6[0]='F';
   s7[0]='%';
   s8[0]='F';
   s9[0]='%';
   s10[0]='F';
*/
   __asm__(

   "add r0,r7,#4\n"
   "add r1,r7,#24\n"
   "bl printf\n"

   "add r0,r7,#104\n"
   "mov r1,r7\n"
   "bl __isoc99_scanf\n"
   "ldr r9,[r7,#0]\n"

   "movw r3,#65519\n"
   "movt r3,32767\n"
   "cmp r9,r3\n"
   "ble T2\n"

   "movw r8,#65534\n"
   "movt r8,32767\n"
   "b T3\n"

   "T2:\n"

   "add r8,r9,#15\n"

   "T3:\n"

   "mov r6,r9\n"
   "b T4\n"

   "T14:\n"

   "mov r5,r6\n"
   "add r0,r7,#84\n"
   "mov r1,r5\n"
   "bl printf\n"

   "movs r4,#2\n"
   "b T5\n"

   "T11:\n"

   "mul r2,r4,r4\n"
   "cmp r2,r5\n"
   "ble T6\n"

   "add r0,r7,#44\n"
   "mov r1,r5\n"
   "bl printf\n"
   "b T7\n"

   "T6:\n"

   "mov r0,r5\n"
   "mov r1,r4\n"
   "bl __aeabi_idivmod\n"

   "cmp r1,#0\n"
   "bne T8\n"

   "mov r0,r5\n"
   "mov r1,r4\n"
   "bl __aeabi_idiv\n"

   "mov r5,r0\n"
   "add r0,r7,#64\n"
   "mov r1,r4\n"
   "bl printf\n"

   "movs r4,#2\n"
   "b T5\n"

   "T8:\n"

   "cmp r4,#2\n"
   "bne T9\n"

   "adds r4,r4,#1\n"
   "b T10\n"

   "T9:\n"

   "adds r4,r4,#2\n"

   "T10:\n"

  "movs r3,#0\n"
  "movw r3,#46339\n"
   "cmp r4,r3\n"
   "ble T5\n"

   "add r0,r7,#4\n"
   "add r1,r7,#124\n"
   "bl printf\n"
   "b T7\n"

   "T5:\n"

   "cmp r4,r5\n"
   "ble T11\n"

   "T7:\n"

   "movw r3,#65533\n"
   "movt r3,32767\n"
   "cmp r6,r3\n"
   "ble T12\n"

   "add r0,r7,#4\n"
   "add r1,r7,#144\n"
   "bl printf\n"
   "b T16\n"

   "T12:\n"

   "adds r6,r6,#1\n"

   "T4:\n"

   "cmp r6,r8\n"
   "ble T14\n"

   "T16:\n"
   );

}

akira@dynabookAZ:~/arm1312$

素因数分解プログラム(再考)

akira@dynabookAZ:~/arm1312$ ./d001
Favorite Number: 7
7=7
8=2*2*2
9=3*3
10=2*5
11=11
12=2*2*3
13=13
14=2*7
15=3*5
16=2*2*2*2
17=17
18=2*3*3
19=19
20=2*2*5
21=3*7
22=2*11
akira@dynabookAZ:~/arm1312$ ./d001
Favorite Number: 10000
10000=2*2*2*2*5*5*5*5
10001=73*137
10002=2*3*1667
10003=7*1429
10004=2*2*41*61
10005=3*5*23*29
10006=2*5003
10007=10007
10008=2*2*2*3*3*139
10009=10009
10010=2*5*7*11*13
10011=3*47*71
10012=2*2*2503
10013=17*19*31
10014=2*3*1669
10015=5*2003
akira@dynabookAZ:~/arm1312$ ./d001
Favorite Number: 12345678
12345678=2*3*3*47*14593
12345679=37*333667
12345680=2*2*2*2*5*154321
12345681=3*1049*3923
12345682=2*1063*5807
12345683=7*103*17123
12345684=2*2*3*13*79139
12345685=5*11*224467
12345686=2*251*24593
12345687=3*3*19*23*43*73
12345688=2*2*2*31*67*743
12345689=17*751*967
12345690=2*3*5*7*58789
12345691=59*209249
12345692=2*2*3086423
12345693=3*71*149*389
akira@dynabookAZ:~/arm1312$ cat d001.c
#include <stdio.h>

main(){
   long a,b,c,m,s,i,e,f,g;
   char s1[20]="%s";
   char s2[20]="Favorite Number: ";
   char s3[20]="%ld\n";
   char s4[20]="%ld*";
   char s5[20]="%ld=";
   char s6[20]="%ld";
   char s7[20]="Kake Over\n";
   char s8[20]="Number Over\n";
   char s9[20]="test1\n";
   char s10[20]="test2\n";
/*
   a=1;
   b=2;
   c=3;
   m=4;
   s=5;
   i=6;
   e=7;
   f=8;
   g=9;
   s1[0]='%';
   s2[0]='F';
   s3[0]='%';
   s4[0]='F';
   s5[0]='%';
   s6[0]='F';
   s7[0]='%';
   s8[0]='F';
   s9[0]='%';
   s10[0]='F';
 */
   printf(s1,s2);
   scanf(s6,&a);

   if(a>=0x7ffffff0) b=0x7ffffffe;
   else              b=a+15;

   for(m=a; m<=b; m++){
      s=m;
      printf(s5,s);
      i=2;
      while(i<=s){
         if(s<i*i){
            printf(s3,s);
            goto F1;
         }
         if(s%i==0){
            s/=i;
            printf(s4,i);
            i=2;
         }
         else{
            if(i==2) i++;
            else     i+=2;
            if(i>=0x0000b504){
               printf(s1,s7);
               goto F1;
            }
         }
      }
F1:i=i;

      if(m>=0x7ffffffe){
         printf(s1,s8);
         return;
      }
   }
}

akira@dynabookAZ:~/arm1312$

2013年12月15日日曜日

32bit整数レジスタを自己流実数レジスタとして扱い平方根を求める

akira@dynabookAZ:~/arm1312$ ./c014
Number: 2   2.0を入力
l=200000    レジスタの中でこれを2.0とする
org. sqrt(dd)=1.4142135624  C言語のmath.hで計算させた参考値
sqrt=1.4142135624     
@@@  sqrt1=  @@@   l=  16a09e   +1.4142131805  自己流で計算させた値
Number: 3
l=300000
org. sqrt(dd)=1.7320508076
sqrt=1.7320508076
@@@  sqrt1=  @@@   l=  1bb67a   +1.7320499420
Number: 0.001
l=418
org. sqrt(dd)=0.0316227766
sqrt=0.0316227766
@@@  sqrt1=  @@@   l=    817d   +0.0316133499
Number: 1678
l=68e00000
org. sqrt(dd)=40.9633982965
sqrt=40.9633982965
@@@  sqrt1=  @@@   l= 28f72e9   +40.9655542373
Number: 2.3333
l=255532
org. sqrt(dd)=1.5275143207
sqrt=1.5275143207
@@@  sqrt1=  @@@   l=  1870b2   +1.5275135040
Number: ^C
akira@dynabookAZ:~/arm1312$ cat c014.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define  x8  0x80000000
#define  x7f 0x7fffffff
#define  xpi 0x3243f6

long main1b();
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);
long mod1(long l1,long l2);
void printl(char *txt,long l);
long sin0(long l1);
long cos0(long l1);
long sin1(long l1);
long cos1(long l1);
long atan1(long l1);
long sqrt1(long l1);

main(){
   long l,l1;

   while(1){
      l=main1b();
      l1=sqrt1(l);
      printl("sqrt1=",l1);
   }
}

long sqrt1(long l1){
   long s1,ld,l5,l2;

   s1=l1&x8;
   l1&=x7f;
   if(s1==x8){
      printf("Minus Over !\n");
      exit(0);
   }
   if(l1==0){ return l1;}
   else if(l1==0x100000){ return l1; }
   else if(0<l1&&l1<0x100000){
      l1=mul1(l1,0x2cb9000);
      ld=l2=l1;
      l5=0;
      while(l5<5){
         l5++;
         ld=mul1(l2,l2);
         ld=add1(ld,l1);
         ld=div1(ld,l2)>>1;
         l2=ld;
      }
      l2=div1(l2,0x6b0000);
      return l2;
   }
   else if(0x100000<l1&&l1<0x2cb9000){
      ld=l2=l1;
      l5=0;
      while(l5<5){
         l5++;
         ld=mul1(l2,l2);
         ld=add1(ld,l1);
         ld=div1(ld,l2)>>1;
         l2=ld;
      }
      return l2;
   }
   else{
      l1=div1(l1,0x2cb9000);
      ld=l2=l1;
      l5=0;
      while(l5<5){
         l5++;
         ld=mul1(l2,l2);
         ld=add1(ld,l1);
         ld=div1(ld,l2)>>1;
         l2=ld;
      }
      l2=mul1(l2,0x6b0000);
      return l2;
   }
}


long sin1(long l1){

   l1=add1(l1,0x3f9e0358);
   l1=mod1(l1,0x6487ec);

   if(0<=l1&&l1<=0x1921fb) return sin0(l1);
   else if(0x1921fb<l1&&l1<=0x3243f6){
      l1=sub1(0x3243f6,l1);
      return sin0(l1);
   }
   else if(0x3243f6<l1&&l1<=0x4b65f1){
      l1=sub1(l1,0x3243f6);
      return sin0(l1)^x8;
   }
   else if(0x4b65f1<l1&&l1<=0x6487ec){
      l1=sub1(0x6487ec,l1);
      return sin0(l1)^x8;
   }

}

long cos1(long l1){

   l1=add1(l1,0x3f9e0358);
   l1=mod1(l1,0x6487ec);

  /*printf("171 l1=%lx   ",l1);*/

   if(0<=l1&&l1<=0x1921fb) return cos0(l1);
   else if(0x1921fb<l1&&l1<=0x3243f6){
      l1=sub1(0x3243f6,l1);
      return cos0(l1)^x8;
   }
   else if(0x3243f6<l1&&l1<=0x4b65f1){
      l1=sub1(l1,0x3243f6);
      return cos0(l1)^x8;
   }
   else if(0x4b65f1<l1&&l1<=0x6487ec){
      l1=sub1(0x6487ec,l1);
      return cos0(l1);
   }

}


long sin0(long l1){
   long l,a1,a2,a3,a4,a5;
 
   a1=div1(l1,6<<20);
   a1=mul1(a1,l1);
   a1=mul1(a1,l1);

   a2=div1(a1,20<<20);
   a2=mul1(a2,l1);
   a2=mul1(a2,l1);

   a3=div1(a2,42<<20);
   a3=mul1(a3,l1);
   a3=mul1(a3,l1);

   a4=div1(a3,72<<20);
   a4=mul1(a4,l1);
   a4=mul1(a4,l1);

   a5=div1(a4,110<<20);
   a5=mul1(a5,l1);
   a5=mul1(a5,l1);

   l=sub1(l1,a1);
   l=add1(l,a2);
   l=sub1(l,a3);
   l=add1(l,a4);
   l=sub1(l,a5);
   return l;
}

long cos0(long l1){
   long l,a1,a2,a3,a4,a5,a6;
 
   a1=div1(l1,2<<20);
   a1=mul1(a1,l1);

   a2=div1(a1,12<<20);
   a2=mul1(a2,l1);
   a2=mul1(a2,l1);

   a3=div1(a2,30<<20);
   a3=mul1(a3,l1);
   a3=mul1(a3,l1);

   a4=div1(a3,56<<20);
   a4=mul1(a4,l1);
   a4=mul1(a4,l1);

   a5=div1(a4,90<<20);
   a5=mul1(a5,l1);
   a5=mul1(a5,l1);
/*
   a6=div1(a5,132<<20);
   a6=mul1(a6,l1);
   a6=mul1(a6,l1);
*/
   l=1<<20;
   l=sub1(l,a1);
   l=add1(l,a2);
   l=sub1(l,a3);
   l=add1(l,a4);
   l=sub1(l,a5);
   /*l=add1(l,a6);*/

   return l;
}

long atan1(long l1){
   long l,b,a1,a2,a3,a4,a5;
 
   b=mul1(l1,l1);
   b=mul1(b,l1);
   a1=div1(b,3<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a2=div1(b,5<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a3=div1(b,7<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a4=div1(b,9<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a5=div1(b,11<<20);

   l=sub1(l1,a1);
   l=add1(l,a2);
   l=sub1(l,a3);
   l=add1(l,a4);
   l=sub1(l,a5);
   return 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 mod1(long l1,long l2){
   l1&=x7f;
   l2&=x7f;

   l1%=l2;
   return l1;
}



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

   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);
   }
   dd=kd+kf;
   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;
   if(js==1) dd*=-1.0;
   printf("l=%lx\n",l);

   if(dd<0.0){
      printf("Minus OVER !\n");
      exit(0);
   }
   printf("org. sqrt(dd)=%3.10f\n",sqrt(dd));

   if(dd==0.0) printf("sqrt=0.0\n");
   else if(dd==1.0) printf("sqrt=1.0\n");
   else{
      ld=dd;
      i5=0;
      while(i5<10){
         ld=(ld*ld+dd)/(2*ld);
         i5++;
      }
      printf("sqrt=%3.10f\n",ld);
   }

   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$

32bit整数レジスタを自己流実数レジスタとして扱いsin,cosを求める

akira@dynabookAZ:~/arm1312$ ./c010
Number: 45   45度をラジアンで計算
l=2d00000   45(10)=2d(16)
sin(dd*pi/180)=0.7071067812   cos(dd*pi/180)=0.7071067812  通常演算(元の参考値)
@@@  sin1(do)=  @@@   l=   b504f   +0.7071065902  自己流で計算した値
@@@  cos1(do)=  @@@   l=   b504f   +0.7071065902
Number: 30
l=1e00000
sin(dd*pi/180)=0.5000000000   cos(dd*pi/180)=0.8660254038  
@@@  sin1(do)=  @@@   l=   7fffe   +0.4999980926
@@@  cos1(do)=  @@@   l=   ddb40   +0.8660278320
Number: 60
l=3c00000
sin(dd*pi/180)=0.8660254038   cos(dd*pi/180)=0.5000000000  
@@@  sin1(do)=  @@@   l=   ddb3d   +0.8660249710
@@@  cos1(do)=  @@@   l=   80001   +0.5000009536
Number: 0
l=0
sin(dd*pi/180)=0.0000000000   cos(dd*pi/180)=1.0000000000  
@@@  sin1(do)=  @@@   l=       0   +0.0000000000
@@@  cos1(do)=  @@@   l=  100000   +1.0000000000
Number: 180
l=b400000
sin(dd*pi/180)=0.0000000000   cos(dd*pi/180)=-1.0000000000  
@@@  sin1(do)=  @@@   l=       0   +0.0000000000
@@@  cos1(do)=  @@@   l=80100000   -1.0000000000
Number: -12.4
l=80c66666
sin(dd*pi/180)=-0.2147353272   cos(dd*pi/180)=0.9766722783  
@@@  sin1(do)=  @@@   l=80036f8d   -0.2147340774
@@@  cos1(do)=  @@@   l=   fa073   +0.9766721725
Number: -33.3
l=8214cccc
sin(dd*pi/180)=-0.5490228180   cos(dd*pi/180)=0.8358073614  
@@@  sin1(do)=  @@@   l=8008c8ca   -0.5490207672
@@@  cos1(do)=  @@@   l=   d5f79   +0.8358087539
Number: ^C
akira@dynabookAZ:~/arm1312$ cat c010.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define  x8  0x80000000
#define  x7f 0x7fffffff
#define  xpi 0x3243f6

long main1a();
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);
long mod1(long l1,long l2);
void printl(char *txt,long l);
long sin0(long l1);
long cos0(long l1);
long sin1(long l1);
long cos1(long l1);
long atan1(long l1);

main(){
   long l,l1,l2,l3,l4;

 while(1){
   l=main1a();
   l=div1(l,180<<20);
   l=mul1(l,xpi);
   l1=sin1(l);
   printl("sin1(do)=",l1);
   l1=cos1(l);
   printl("cos1(do)=",l1);
 }
}

long sin1(long l1){

   l1=add1(l1,0x3f9e0358);
   l1=mod1(l1,0x6487ec);

   if(0<=l1&&l1<=0x1921fb) return sin0(l1);
   else if(0x1921fb<l1&&l1<=0x3243f6){
      l1=sub1(0x3243f6,l1);
      return sin0(l1);
   }
   else if(0x3243f6<l1&&l1<=0x4b65f1){
      l1=sub1(l1,0x3243f6);
      return sin0(l1)^x8;
   }
   else if(0x4b65f1<l1&&l1<=0x6487ec){
      l1=sub1(0x6487ec,l1);
      return sin0(l1)^x8;
   }

}

long cos1(long l1){

   l1=add1(l1,0x3f9e0358);
   l1=mod1(l1,0x6487ec);

  /*printf("171 l1=%lx   ",l1);*/

   if(0<=l1&&l1<=0x1921fb) return cos0(l1);
   else if(0x1921fb<l1&&l1<=0x3243f6){
      l1=sub1(0x3243f6,l1);
      return cos0(l1)^x8;
   }
   else if(0x3243f6<l1&&l1<=0x4b65f1){
      l1=sub1(l1,0x3243f6);
      return cos0(l1)^x8;
   }
   else if(0x4b65f1<l1&&l1<=0x6487ec){
      l1=sub1(0x6487ec,l1);
      return cos0(l1);
   }

}


long sin0(long l1){
   long l,a1,a2,a3,a4,a5;
 
   a1=div1(l1,6<<20);
   a1=mul1(a1,l1);
   a1=mul1(a1,l1);

   a2=div1(a1,20<<20);
   a2=mul1(a2,l1);
   a2=mul1(a2,l1);

   a3=div1(a2,42<<20);
   a3=mul1(a3,l1);
   a3=mul1(a3,l1);

   a4=div1(a3,72<<20);
   a4=mul1(a4,l1);
   a4=mul1(a4,l1);

   a5=div1(a4,110<<20);
   a5=mul1(a5,l1);
   a5=mul1(a5,l1);

   l=sub1(l1,a1);
   l=add1(l,a2);
   l=sub1(l,a3);
   l=add1(l,a4);
   l=sub1(l,a5);
   return l;
}

long cos0(long l1){
   long l,a1,a2,a3,a4,a5,a6;
 
   a1=div1(l1,2<<20);
   a1=mul1(a1,l1);

   a2=div1(a1,12<<20);
   a2=mul1(a2,l1);
   a2=mul1(a2,l1);

   a3=div1(a2,30<<20);
   a3=mul1(a3,l1);
   a3=mul1(a3,l1);

   a4=div1(a3,56<<20);
   a4=mul1(a4,l1);
   a4=mul1(a4,l1);

   a5=div1(a4,90<<20);
   a5=mul1(a5,l1);
   a5=mul1(a5,l1);
/*
   a6=div1(a5,132<<20);
   a6=mul1(a6,l1);
   a6=mul1(a6,l1);
*/
   l=1<<20;
   l=sub1(l,a1);
   l=add1(l,a2);
   l=sub1(l,a3);
   l=add1(l,a4);
   l=sub1(l,a5);
   /*l=add1(l,a6);*/

   return l;
}

long atan1(long l1){
   long l,b,a1,a2,a3,a4,a5;
 
   b=mul1(l1,l1);
   b=mul1(b,l1);
   a1=div1(b,3<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a2=div1(b,5<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a3=div1(b,7<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a4=div1(b,9<<20);

   b=mul1(b,l1);
   b=mul1(b,l1);
   a5=div1(b,11<<20);

   l=sub1(l1,a1);
   l=add1(l,a2);
   l=sub1(l,a3);
   l=add1(l,a4);
   l=sub1(l,a5);
   return 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 mod1(long l1,long l2){
   l1&=x7f;
   l2&=x7f;

   l1%=l2;
   return l1;
}



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

   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);
   }
   dd=kd+kf;
   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;
   if(js==1) dd*=-1.0;
   printf("l=%lx\n",l);
   printf("sin(dd*pi/180)=%3.10f   cos(dd*pi/180)=%3.10f   \n",sin(dd*M_PI/180.),cos(dd*M_PI/180.));
   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$

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$

2013年12月11日水曜日

小数点以下を16進にするc002.c

main1()=scanfで取り込んだ値を16進に変換する
printl()=16進の値をprintf()する


31bit   <=======>      0bit

33222222222211111111110000000000
10987654321098765432109876543210

符号:7| F | F | F | F | F | F | F |
         |
   整数部  <--|--> 小数部

31bit目=符号フラグ
30〜20bit目=整数部
19〜0bit目=小数部


入力で13.5と打った場合、d.80000となり
d(16)=13(10)
0x.80000(16)=0.5(10)

-13.5と打った場合、80d.80000となり
最初の8が符号フラグのためビットが立つ

akira@dynabookAZ:~/arm1312$ g c002
akira@dynabookAZ:~/arm1312$ ./c002
Number: 13.5
l=d80000
  +13.5000000000
akira@dynabookAZ:~/arm1312$ ./c002
Number: -13.5
l=80d80000
  -13.5000000000


akira@dynabookAZ:~/arm1312$ ./c002
Number: .4
l=66666
   +0.3999996185

0.4(10)は0x.66666(16)
0.6(10)は0x.99999(16)

多少誤差が出ます

akira@dynabookAZ:~/arm1312$ ./c002
Number: .6
l=99999
   +0.5999994277
akira@dynabookAZ:~/arm1312$






akira@dynabookAZ:~/arm1312$ cat c002.c
#include <stdio.h>
#include <stdlib.h>

long main1();
void printl(long l);

main(){
   long l;
   l=main1();
   printl(l);
}

long main1(){
   char ss[100]="                            ";
   long l,l2;
   int  i,kd=0,ke=0,jf=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^=0x80000000;
   printf("l=%lx\n",l);
   /*printf("a=%d %ld\n",kd,(long)1<<20);*/
   return l;
}

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

   if(l<0){ dotf=1; l^=0x80000000; }
   /*printf("%+5ld.",l);*/
   i=l>>20;
   if(dotf==1) i=-i;
   printf("%+5ld.",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$