ORACLE NUMBER类型内部实现

先来研究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. }
时间: 2024-08-01 21:16:17

ORACLE NUMBER类型内部实现的相关文章

oracle中dump函数及oracle NUMBER类型内部存储机制

oracle中dump函数 转自:http://blog.vsharing.com/nimrod/A654847.html DUMP函数的输出格式类似: 类型 ,符号/指数位 [数字1,数字2,数字3,......,数字20] 各位的含义如下: 1.类型: Number型,Type=2 (类型代码可以从Oracle的文档上查到) 2.长度:指存储的字节数 3.符号/指数位 在存储上,Oracle对正数和负数分别进行存储转换: 正数:加1存储(为了避免Null)负数:被101减,如果总长度小于21

ORACLE NUMBER类型详解

1>.NUMBER类型细讲:Oracle number datatype 语法:NUMBER[(precision [, scale])]简称:precision --> p      scale     --> s NUMBER(p, s)范围: 1 <= p <=38, -84 <= s <= 127保存数据范围:-1.0e-130 <= number value < 1.0e+126   保存在机器内部的范围: 1 ~ 22 bytes 有效为:

ORACLE NUMBER类型Scale为0引发的问题

今天遇到了一个很有意思的NUMBER类型Scale引发的问题,我用一个简单的测试用例来展示一下这个案例.假如有个TEST的表,有个字段类型为NUMBER,我插入下面两条数据 CREATE TABLE TEST (      Category VARCHAR(12),      QTY  NUMBER )   INSERT INTO TEST SELECT 'M', 12 FROM DUAL UNION ALL SELECT 'C', 0.99999999999999999 FROM DUAL;

ORACLE 中NUMBER类型默认的精度和Scale问题

在ORACLE数据库中,NUMBER(P,S)是最常见的数字类型,可以存放数据范围为10^-130~10^126(不包含此值),需要1~22字节(BYTE)不等的存储空间.P 是Precison的英文缩写,即精度缩写,表示有效数字的位数,最多不能超过38个有效数字.S是Scale的英文缩写,表示从小数点到最低有效数字的位数,它为负数时,表示从最大有效数字到小数点的位数.有时候,我们在创建表的时候,NUMBER往往没有指定P,S的值,那么默认情况下,NUMBER的P.S的值分别是多少呢?相信这个问

Oracle中的number类型

number类型用于定义固定长度的数字,可以使整数,也可以是实数.number(p,s)是完整的定义形式. p必须是整数,取值范围是1-38,用于指定数字的总的位数.s必须是整数,取值范围是-84~127,用于指定小数点之后的位数. NUMBER 赋值:1234.56 实际:1234.56 NUMBER(3) 赋值:-123 实际:-123 NUMBER(3) 赋值:1234 实际:错误(ORA-06502:PL/SQL:数字或值错误:数字精度太高) NUMBER(4,3) 赋值:1.23456

[20150503]关于oracle的number类型.txt

[20150503]关于oracle的number类型.txt --节前的事情,别人建表使用number类型,本来想定义成number(10,2),结果少输入0,变成number(1,2). --在我的记忆里,好像前面的数值应该大于后面的精度的,没想到这样竟然可以通过,自己感到很奇怪! --测试下来,才知道自己oracle基本的东西都不是很清楚. 1.首先提到我以前写的一篇blog: [20140823]在sqlplus使用copy注意.txt http://blog.itpub.net/267

Oracle Number型数值存储与转换的实现详解_oracle

Oracle在数据库内部通过相应的算法转换来进行数据存储,本文简单介绍Oracle的Number型数值存储及转换.这个内容是为了回答留言板上的2119号问题.我们可以通过DUMP函数来转换数字的存储形式,一个简单的输出类似如下格式: 复制代码 代码如下: SQL> select dump(1) from dual;DUMP(1)            ------------------            Typ=2 Len=2: 193,2 DUMP函数的输出格式类似:类型 <[长度]&

Oracle Lob类型存储浅析

  在Oracle中,为数据表字段column和PL/SQL语言,分别提供了多种数据类型,以应对实际开发中的多种类型.Lob类型是Oracle推出一种保存大对象的数据类型.当我们考虑将信息文件(十进制.二进制).图像甚至音频信息采用数据库作为保存载体时,就需要使用lob类型数据.   目前Oracle支持的Lob类型具体包括四个子类型(subtype),分别为CLOB.BLOB.NLOB和BFILE.其中,CLOB.BLOB和NLOB都是将数据保存在数据库内部,而BFILE类型保存的核心是文件指

mybatis怎么读取oracle xmltype类型的数据

问题描述 mybatis怎么读取oracle xmltype类型的数据 1.oracle 用的是字段类型是xmltype BOOK_ID NUMBER BOOK_NAME XMLTYPE BOOK_PRICE NUMBER 2.JavaBean对应的属性是Object private Integer bookId; private Object bookName; private Integer bookPrice; 3.mapper.xml 对应jdbcType=CLOB <resultMap