ORACLE NUMBER型別內部實現

gaopengtttt發表於2016-11-16
先來研究NUMBER型別的數字回推演算法
型別 <[長度]>,符號/指數位 [數字1,數字2,數字3,......,數字20]
1、長度型別沒什麼號說的
2、符號位,這個需要說一下
The sign bit, which is the high order bit (128)
按照文件的說法這個判斷方法是和128進行最高位按位與出來的,如果
這位小於128則是負數,我們使用127試試吧

128的二進位制為1000 0000 
127的二進位制為0111 1111
最高位1&0=0 則代表他是負數,

如果是129則是正數
128的二進位制為1000 0000 
129的二進位制為1000 0001
最高位1&1=1 則代表他是正數,
3、指數位
正數
128固定為正負數的判斷
65固定 The offset, which is always 65
那麼就是128+65=193就是正數指數的固定數值

負數
固定為62為負數的固定數值

4、數字位
正數
那我們來判斷這樣一個數字
193,64,13,31
那麼就是
193-193=0
(64-1)*100^(0-0) =63
(13-1)*100^(0-1) =0.12
(31-1)*100^(0-2) =0.0030
為63.123

負數
62,38,89,71,102
62-62=0
101-38 = 63 *100^(0-0)=63
101-89 = 12 *100^(0-1)=0.12
101-71 = 30 *100^(0-2)=0.003
102 為排序位不用理會
所以為-63.123

研究了數字的演算法接下來我們使用C語言進行實現
考慮實際的16進位制格式
4,c1,40,d,1f      63.123
5,3e,26,59,47,66  -63.123
04,c1,40,0d,1f,05,3e,26,59,47,66
早期我寫過一個C語言程式使用位域來完成,因為有點久遠了我也不太記得是否驗證過不過先放到這裡

點選(此處)摺疊或開啟

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>



  4. double number(int sseek)
  5. {
  6.     struct bin1b
  7.     {
  8.         unsigned a1:1;
  9.         unsigned a2:1;
  10.         unsigned a3:1;
  11.         unsigned a4:1;
  12.         unsigned a5:1;
  13.         unsigned a6:1;
  14.         unsigned a7:1;
  15.         unsigned a8:1;
  16.     };
  17.     int sseek=8182;//設定偏移量後期可以直接推算出來
  18.     int clg,digt,i;
  19.     double a=0.0;
  20.     char clgc;
  21.     char *Ptr;
  22.     int *Ptrn;
  23.     struct bin1b *data;
  24.     FILE *fp;
  25.     fp=fopen("D:\\c\\95393.dbf","rb");
  26.     if(!fp)
  27.     {
  28.         printf("can't open this file!");
  29.     }
  30.     else
  31.     {
  32.         fseek(fp,sseek+1,0);
  33.         fread(&clgc,1,1,fp);
  34.         printf("%d\n",ftell(fp));
  35.         clg=clgc;
  36.         Ptr=(char *)malloc(clg); //分配欄位長度的一個4個單位元組記憶體空間
  37.         Ptrn=(int *)malloc(sizeof(int)*clg);
  38.         fread(Ptr,1,clg,fp);
  39.         printf("%d\n",ftell(fp));
  40.         for(i=0;i<clg;i++)
  41.         {
  42.             data=&Ptr[i];
  43.             Ptrn[i]=data->a1+data->a2*2+data->a3*pow(2,2)+data->a4*pow(2,3)+data->a5*pow(2,4)+data->a6*pow(2,5)+data->a7*pow(2,6)+data->a8*pow(2,7);
  44.             printf("%d\n",Ptrn[i]);
  45.         }
  46.         
  47.         for(i=0;i<clg;i++)
  48.         {
  49.             if(Ptrn[0]<128)
  50.             {
  51.                 digt=62-Ptrn[0];
  52.                 if((i>0) && (Ptrn[i]!=102))
  53.                 {
  54.                     a=a+(101-Ptrn[i])*pow(100,(digt-(i-1)));
  55.                 }
  56.             }
  57.             if(Ptrn[0]>128)
  58.             {
  59.                 digt=Ptrn[0]-193;
  60.                 if(i>0 )
  61.                 {
  62.                     a=a+(Ptrn[i]-1)*pow(100,(digt-(i-1)));
  63.                 }
  64.             }
  65.         }
  66.         if(Ptrn[0]<128)
  67.         {
  68.             a=-a;
  69.         }
  70.         else
  71.         {
  72.             a=a;
  73.         }
  74.         
  75.          return(a);
  76.         free(Ptr);
  77.          free(Ptrn);
  78.     }
  79.     fclose(fp);
  80. }



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2128563/,如需轉載,請註明出處,否則將追究法律責任。

相關文章