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$

0 件のコメント:

コメントを投稿