oracle binary_float
来源:互联网 发布:淘宝面包鞋豆豆鞋 编辑:程序博客网 时间:2024/06/06 01:21
/ 我有一个表如下:
createtable A_TEST
(
id_n NUMBER,
val_f BINARY_FLOAT,
val_d BINARY_DOUBLE
);
// 插入一条数据
INSERTINTO A_TEST(ID_N, VAL_F,VAL_D) VALUES (0.1, 0.1, 0.1);
// 如出刚才的数据发现binary_float 显示不对
SELECT * FROM A_TEST;
// 用程序查询的结果是对的
ResultSet set = oracle_stmt
.executeQuery("select id_n, val_f, val_d from A_TEST");
while(set.next()) {
System.out.println(set.getString(1) + ", "
+ set.getFloat(2)+ ", "
+ set.getDouble(3));
}
// 程序查询的返回值是这样的
// .1, 0.1, 0.1
先了解下binary_float与binary_double 的内存存储方式:
http://blog.csdn.net/yidian815/article/details/12912661
binary_float 4字节 32位:
符号位S(1位) 指数位E(8位) 尾数位M(23位)
binary_double 8 字节 64位
符号位S(1位) 指数位E(11位) 尾数位M(52位)
与浮点数对应数学值计算方法为:v=(-1)^s*M*2^E.
为了便于比较两个浮点数的大小,指数部分采用无符号整数来存储,但是为了解决指数为负数的情况,IEEE 754规定,指数域的存储值为实际值和指数偏移量之和,指数偏移量的计算方法为2^(e-1) - 1
指数E(存储值) = V(实际值) + 2^(e-1) – 1(e 为指数位数)
如E(存储值) 129, 那么V(实际值) = 129 – 2 ^ (8-1) -1 = 2
例子:
123.625(10进制)à 1111011.101(2进制)à 1.111011101*2^6。
将1.111011101去除首部的1(任何二进制转换为科学计数法后,其整数部分必为1(尾数域范围为【1-2)),因此可以在尾数域中忽略该位,以便存储更多的数据
M = 1.111011101à111011101à11101110100000000000000(填充0)
S = 0
E = 10000101
按照相反的过程,我们可以推倒出 0 10000101 11101110100000000000000à
0 134 11101110100000000000000à
0 6 1.111011101à 1.111011101*2^6 à 123.625
根据上面的理论 0.1(十进制) à 0. 0001 1001 1001 1001 10011001 ……
十进制小数转二进制小数使用乘2取整数法:
0.1*2=0.2 整数为:0
0.2*2=0.4 整数为:0
0.4*2=0.8 整数为:0
0.8*2=1.6 整数为:1
0.6*2=1.2 整数为:1
0.2*2=0.4 …
二进制小数转十进制小数:
0. abcd = a *2^-1 + b * 2^-2 + c * 2^-3 …..
java 代码实现二进制与十进制相互转换:
publicclassTodeimal {
publicstaticvoidmain(String[] args)throwsException {
Todeimal t = new Todeimal();
List<Integer> binary = t.toBinary(0.1D, 23);
System.out.println();
t.toDecimal(binary);
t.toDecimal("00011001100110011001101",23);
}
publicvoidtoDecimal (String binary,intmax){
doubleres = 0;
intj = 0;
for (inti=0; i<max; i++) {
intbit = Integer.valueOf(String.valueOf(binary.charAt(i)));
res += bit * Math.pow(2, --j);
}
System.out.println("四舍五入: " + res);
}
publicvoidtoDecimal (List<Integer> binary) {
doubleres = 0;
intj = 0;
for (Integer b : binary) {
res += b * Math.pow(2, --j);
}
System.out.println("不舍入: " + res);
}
publicList<Integer> toBinary(Double f, intmax){
if (f >= 1 || f<= 0)
returnnull;
List<Integer> list = newArrayList<Integer>();
intbits = 0;
while (true) {
f = calc(f, list);
bits++;
if (bits == 50) {
System.out.println();
}
if (bits == max)
break;
}
System.out.println("len: " + list.size());
for (Integer i : list) {
System.out.print(i);
}
returnlist;
}
privateDouble calc(Double f,List<Integer> list){
if (f == 0 )
return -1D;
Double t = f * 2;
if (t >= 1) {
list.add(1);
returnt - 1;
} else {
list.add(0);
returnt;
}
}
}
通过上面的计算方法把0.1存储数据库再取出来结果应该是:
select to_char(id_n),to_char(val_f), val_f, to_char(val_d), val_d
from A_TEST;
binary_float: 1.00000001E-001
binary_double: 1.0000000000000001E-001
由于plsql 在显示两种类型时取值精度不一样就成了不同的显示效果
为了证明是显示精度的问题:
INSERTINTO A_TEST(ID_N, VAL_F,VAL_D)
VALUES (0.1, 0.5, to_number(1.0000000000000101E-001))
同样在程序中查询的效果也是因为精度问题所以显示没有问题
- oracle binary_float
- Oracle binary_float和binary_double
- Oracle binary_float和binary_double类型的特殊值实例
- ORACLE数值类型详解--NUMBER、FLOAT、BINARY_FLOAT、BINARY_DOUBLE、BINARY_INTEGER
- ORACLE数值类型详解--NUMBER、BINARY_FLOAT、BINARY_DOUBLE、BINARY_INTEGER、FLOAT
- Oracle 11g学习笔记--binary_float和binary_double数据类型
- Oracle Database 11g SQL 开发指南学习笔记:binary_float和binary_double数据类型
- number 和binary_float binary_double 性能比较
- Oracle???
- oracle
- oracle
- oracle
- oracle
- oracle...
- oracle
- oracle
- ORACLE
- Oracle
- 利用遗传算法求出下面函数的极小值:z=2-exp[-(x2+y2)]
- linux文件3种身份&3种权限
- android手机振动
- linux ioctl()函数
- strchr 的初学者应用
- oracle binary_float
- 3ds2mesh_cpp
- HDU1285 确定比赛名次(拓扑排序)
- 安装.NetFarmWork是提示出现:Setup cannot continue because the version of the .NET Framework is incompatible
- app 主题切换
- 调整上传服务器图片的方向
- 解题报告 之 UVA563 Crimewave
- 推荐!国外程序员整理的机器学习资源大全
- POJ2185 Milking Grid【KMP】