关于oralce数值存储

今天做dump的时候,对oracle的数字存储规则不是明白,就查了一些资料,这个资料不错

http://www.jlcomp.demon.co.uk/number_format.html (来自  : Jonathan Lewis)

做简单翻译如下:

JL Computer Consultancy---一家咨询公司

How are numbers stored.
ORACLE数据库如何存储数字

November 2001 ---初始版本
Updated: Feb 1020 --更新于2010年2月

I was recently (Nov 2001) asked to explain how to translate a number from Oracle‘s internal database format to a human readable form. I know that I have seen a description somewhere in one of the manuals of how Oracle does this, but it always takes ages to find anything in the manuals when I really want to, so I did a few quick tests with the dump() function, and came up with the following.
在2001年11月份,有人问我一个问题, 如何转化一个oracle内部数据库格式到人类可以理解的格式, 我记得曾经在某份oracle的文档见过如何处理这个事情,但是当我想要找出这份文档时,必定要花费不少的时间, 所以我采用了另外一个方式,快速的利用函数dump做一些测试,然后得到了如下的总结。
If you want to repeat the experiments - the command is::
如果你想要重复这些实验--命令如下
select dump({number},10) from dual; -- decimal dump
以10进制格式导出
select dump({number},16) from dual; -- hex dump
以16进制格式导出
The rules of the format appear to be as follows:
规则转化规则大致如下
Step 1: Precision
第一步,精度
If the internal representation of the number ends in 102 (Hex 0x66)
如果数字的内部表示以102(16进制的0x66)结尾
it is negative
表示这个是个负数
discard the last number (102 / 0x66)
除去最后这个数字(102 / 0x66)
subtract the 2nd through to penultimate numbers from 101 (Hex 0x65)
对于从第二个数字开始到最后一个数字,每个都被101减(101-x),得到一个新的数字
else
it is positive
数字不是以102结尾,那么这个数字就是正数
subtract one from the 2nd through to final numbers
对于从第二个数字开始到最后一个数字,每个减去1得到一个新的数字
end if
Write out each converted number using 2 digits (i.e. leading zeros where needed). Put a decimal point after the first adjusted number.
对于每个经过上述转化过的数字,我们用两位数字表示(举例. 如果需要的话,前面需要加0),在第一个转化过的数字后添加小数点。

Step 2: Scale
第二部 伸缩比例
If the number is negative (ended in 102 / 0x66) then
如果这个数字式负的,那么
The first number of the internal representation is 62 (hex 0x3e) plus the power of 100 to DIVIDE by
那么第一个内部数字为62和某个指数之和,这个指数被用在100之上并且结果是用来做除法的
else
the first number of the internal representation is 193 (hex 0xc1) plus the power of 100 to MULTIPLY by
那么第一个内部数字为193和某个指数之和,这个指数被用在100之上并且结果是用来做乘法的
end if.
There is one special case - zero is represented by a single byte 0x80.
但是有一个特例, 0被表示成一个单字节0x80

Example 1: --样例1
c3 2 2e = 195 2 46
The number is positive (doesn‘t end in 102 / 0x66)
这个数字没有以102结尾,所以是正的
(2,46) --> 01 45 --> 1.45
2-1=1 01
46-1=45 45
这里第一个数字是01, 所以结果为 01.45
195 = 193 + 2 --> multiply by 100 twice
指数部分为2,就是 100的2次方即为 10000
Answer 14,500
所以结果为 : 1.45 * 10000 = 14500

Example 2: ---样例2
be 2e 3d = 190 46 61
The number is positive
这个数字没有以102结尾,所以是正的
(46, 61) --> 45 60 --> 45.60
46-1 =45
61-1 = 60
这里第一个数字是45, 所以结果为 45.60
190 = 193 - 3 --> negative so divide by 100 three times
指数部分为-3,就是 100的负3次方即为 0.0000001
Answer 0.0000456
所以结果为 45.6 * 0.0000001 = 0.0000456
Example 3: --样例3
40 1c 3d 66 = 64 28 61 102
The number is negative (ends in 102 / 0x66)
这个数字以102结尾,所以是负的
(28, 61) --> 73 40 --> 73.40 (101 - 28 = 73 etc.)
101-28 = 73
101-61 = 40
这里第一个数字是73, 所以结果为 -73.40
64 = 62 + 2 --> divide by 100 two times
指数部分为2,就是100的2次方即为 10000
Answer -0.00734
结果就是-73.40 / 10000 = -0.00734
Example 4: --样例4
3c 5d 8 25 43 66 = 60 93 8 37 67 102
The number is negative
这个数字以102结尾,所以是负的
(93, 8, 37, 67) --> 8 93 64 34 --> 8.936434
101-93=8 08
101 -8 =93
101 - 37 = 64
101 - 67 = 34
这里第一个数字是08, 所以结果为 -8.936434
60 = 62 - 2 --> negative so multiple by 100 twice
指数部分为-2,就是100的负2次方即为 0.00001
Answer -89364.34
所以结果为 -8.936434 / 0.00001 = -89364.34
Update Feb 2010:
更新于2010年10月
I’ve been sent an example by Steve Aaron of Barclays Capital show that the “negative number end in 0x66” rule breaks down for very large numbers. Here’s an extract from his demonstration:
我从Barclays Capital公司的 Steve Aaron 处收到一份信息, 显示大的负数不一定以 102 结尾,下面是他给的一个例子
create table numtest (n number);
insert into numtest values (-1111111111111111111111111111111111110703);
column n format 9,999,999,999,999,999,999,999,999,999,999,999,999,999
column dumped format a78
select n, dump(n,16) dumped from numtest;
N
------------------------------------------------------
DUMPED
------------------------------------------------------------------------------
-1,111,111,111,111,111,111,111,111,111,111,111,110,703
Typ=2 Len=21: 2b,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5a,5e,62

1 row selected.
Interestingly, the largest precision you can define for a number is number(38) – but if you don’t declare a precision you can get number of up to 40 digits of precision into the database – and it seems to be numbers that go beyond 38 digits of precision where the rule breaks.
有趣的是,最大值的精度已经超过oracle可以定义的最大值38位,你不可能把40位精度的数字插入到数据库中, 验证的结果显示所有超过38位精度的数字都会打破这个规则

时间: 2024-11-05 19:05:11

关于oralce数值存储的相关文章

从java toBinaryString() 看计算机数值存储方式(原码、反码、补码)

一.toBinaryString 方法及其含义 1.1 方法说明 该方法位于java.lang.Integer类中 方法签名:public static String toBinaryString(int i) 含义:返回参数数值的补码形式,正数则忽略前面的0.(官方注释:返回表示传入参数的一个无符号(这里无符号大概单纯指数值前面没有+-号,实则是有符号位) 的二进制字符串.如果参数为负数x,返回的值则为 2^32 + x [就是它的补码]) 1.2 使用示例 System.out.printl

4 C 语言 数值存储方式 数组

源码 补码 反码 数组定义,初始化,使用,随机数 找最大数,逆置,冒泡排序, scanf 输入字符串 字符串处理 字符串溢出等问题 scanf() gets() puts() fputs() strlen() strcat() strncat() strcmp() strncmp() strchr() strstr() strtok() atoi() atof() atol() C 字符串数组 定义数组 遍历输出数组每个元素的值 //GCC 编译方式: C:\MinGW\project>gcc 

一道题回顾计算机数值存储方式-原码,反码,补码

突然想到了计算机的补码,现在利用这个题目回顾一下相关知识点 unsigned char ch = -1; int val = ch; val的最终值是255: 换算成二进制一下,-1的源码:1000 0001,反码:1111 1110 ,负数在计算机中是以补码形式存储的,-1的补码:1111 1111 ch 变量是 无符号的,也就是整个补码的二进制位都是数值位,1111 1111 二进制位换算成十进制就是255,最终赋值给整数结果自然也是255 这道题目考察的就是计算机数值的存储方式,对于正数,

数值存储

以补码存储 十进制&二进制转换,表格法 如,123D -> 01111011B 单精度浮点存储 符号位(1 Sign):0正,1负: 指数位(8 Exponent):需要加偏置值Bias,127 + 指数值: 尾数部分(23 Mantissa):弃小数点前那个恒1并在右端以0补全位数: 如,1234.625F -> 100 1101 0010.101 -> 1.00 1101 0010 101 * 2^10 Sign 0 Exponent   10,127+10 -> 10

ORALCE逻辑存储结构

ORACLE逻辑存储结构块: 数据块 他是最基础的逻辑存储单元,数据以行的形式存储到我么的数据块中 区 :多个块的集合 并且区组成了物理的数据文件 段 :(表 索引 物化视图 物化视图日志 大对象 大对象) 那么在括号中的每一个对象都是一个段.而区由组成了段[逻辑的方式] 一个段中包含多个数据文件 表空间 :表空间指的是段的集合 一个表空间中存在多个段的是 (小表空间) 但是有种特殊的表空间叫(大表空间) 比如说 BLOB CLOB BFILE.....这些都是大表空间中存储的数据,并且大表空间

***mysql中经度纬度字段用什么存储(关于mysql的float和decimal区别)

float,decimal精确度比较 float,double容易产生误差,对精确度要求比较高时,建议使用decimal来存,decimal在mysql内存是以字符串存储的, 用于定义货币要求精确度高的数据.在数据迁移中,float(M,D)是非标准定义,最好不要这样使用.M为精度,D为标度. mysql>  create table t1(c1 float(10,2), c2 decimal(10,2),c3 float); // 10不包括小数点 mysql>  insert into t

Sqlite3中存储类型和数据类型结合文档解析。

sqlite3是个很小的数据库,运行在手机,机顶盒上....那它就不可能像musql,sqlserver那么规范,有很多的数据类型,之前我也以为它定义了很多数据类型,其实不是他就5个存储类,那么多数据类型是根据一整套严谨的规则映射的!!还有什么char,varchar其实都是没有的..下面将结合文档详细讲解,相信看完你会了解更多,其实主要就是翻译文档.... sqlite官网:http://www.sqlite.org/ Sqlite3数据类型 大多数的数据库引擎(到现在据我们所知的除了sqli

MIFARE系列5——存储结构

Mifare S50把1K字节的容量分为16个扇区(Sector0-Sector15),每个扇区包括4个数据块(Block0-Block3),我们也将16个扇区的64个块按绝对地址编号为0~63,每个数据块包含16个字节(Byte0-Byte15),64*16=1024. Mifare S70把4K字节的容量分为40个扇区(Sector0-Sector39),其中前32个扇区(Sector0-Sector31)的结构和Mifare S50完全一样,每个扇区包括4个数据块(Block0-Block

ECMA Script 6_数值的扩展

1. 二进制 和 八进制 新的表示法 前缀 0b(或0B) 表示 二进制 前缀 0o(或 0O )表示 八进制 console.log(0b111110111 === 503); // true console.log(0o767 === 503); // true 如果要将 0b 和 0o 前缀的字符串数值 转为十进制,要使用 Number() 方法 2. Number.isFinite() 检查一个数值是否为有限的(finite),即 不是 Infinity 返回 true 只对数值有效 如