总结:对于单精度浮点数Float: 当数据范围在+-131072(65536×2)以内的时候,float数据精度是正确的,但是超出这个范围的数据就不稳定,没有发现有相关的参数设置建议:将float改成double或者decimal,两者的差别是double是浮点计算,decimal是定点计算,会得到更精确的数据。
分析如下:
一、浮点数的概念及误差问题:
浮点数是用来表示实数的一种方法,它用 M(尾数) * B( 基数)的E(指数)次方来表示实数,相对于定点数来说,在长度一定的情况下,具有表示数据范围大的特点。但同时也存在误差问题,这就是著名的浮点数精度问题!
浮点数有多种实现方法,计算机中浮点数的实现大都遵从 IEEE754 标准,IEEE754 规定了单精度浮点数和双精度浮点数两种规格,单精度浮点数用4字节(32bit)表示浮点数,格式是:1位符号位 8位表示指数 23位表示尾数;双精度浮点数8字节(64bit)表示实数,格式是:1位符号位 11位表示指数 52位表示尾数。同时,IEEE754标准还对尾数的格式做了规范:d.dddddd...,小数点左面只有1位且不能为零,计算机内部是二进制,因此,尾数小数点左面部分总是1。显然,这个1可以省去,以提高尾数的精度。由上可知,单精度浮点数的尾数是用24bit表示的,双精度浮点数的尾数是用53bit表示的,转换成十进制:
2^24 - 1 = 16777215
2^53 - 1 = 9007199254740991
由上可见,IEEE754单精度浮点数的有效数字二进制是24位,按十进制来说,是8位;双精度浮点数的有效数字二进制是53位,按十进制来说,是16 位。
显然,如果一个实数的有效数字超过8位,用单精度浮点数来表示的话,就会产生误差!同样,如果一个实数的有效数字超过16位,用双精度浮点数来表示,也会产生误差!
例如:对于 1310720000000000000000.66 这个数,有效数字是24位,用单精度或双精度浮点数表示都会产生误差,只是程度不同:
单精度浮点数: 1310720040000000000000.00
双精度浮点数: 1310720000000000000000.00
双精度差了 0.66 ,单精度差了近4万亿!以上说明了因长度限制而造成的误差,但这还不是全部!采用IEEE754标准的计算机浮点数,在内部是用二进制表示的,但在将一个十进制数转换为二进制浮点数时,也会造成误差,原因是不是所有的数都能转换成有限长度的二进制数。对于131072.32 这个数,其有效数字是8位,按理应该能用单精度浮点数准确表示,为什么会出现偏差呢?看一下这个数据二进制尾数就明白了 10000000000000000001010001......显然,其尾数超过了24bit,根据舍入规则,尾数只取 100000000000000000010100,结果就造成测试中遇到的“奇怪”现象!131072.68 用单精度浮点数表示变成 131072.69 ,原因与此类似。实际上有效数字小于8位的数,浮点数也不一定能精确表示,7.22这个数的尾数就无法用24bit二进制表示,当然在数据库中测试不会有问题(舍入以后还是7.22),但如果参与一些计算,误差积累后,就可能产生较大的偏差。
二、mysql 和 oracle中的数值类型:
问题是不是只有 mysql 存在呢?
显然不是,只要是符合IEEE754标准的浮点数实现,都存在相同的问题。
mysql中的数值类型(不包括整型):
IEEE754 浮点数: float(单精度),double或 real(双精度)
定点数: decimal 或 numeric
oracle中的数值类型:oracle 浮点数 :number (注意不指定精度)
IEEE754浮点数: BINARY_FLOAT(单精度) ,BINARY_DOUBLE (双精度)
FLOAT,FLOAT(n) (ansi要求的数据类型) 定点数:number(p,s)
如果在oracle中,用BINARY_FLOAT等来做测试,结果是一样的。
因此,在数据库中,对于涉及货币或其他精度敏感的数据,应使用定点数来存储,对mysql来说是 decimal,对oracle来说就是number(p,s)。双精度浮点数,对于比较大的数据同样存在问题!
三、编程中也存在浮点数问题:
不光数据库中存在浮点数问题,编程中也同样存在,甚至可以说更值得引起注意!
通过上面的介绍,浮点数的误差问题应该比较清楚了。如果在程序中做复杂的浮点数运算,误差还会进一步放大。因此,在程序设计中,如果用到浮点数,一定要意识到可能产生的误差问题。不仅如此,浮点数如果处理不好,还会导致程序BUG!
看下面的语句:
if (x != y)
{
z = 1 / (x -y);
}
这个语句看起来没有问题,但如果是浮点数,就可能存在问题!
再看下面的语句会输出什么结果:
public class Test
{
public static void main(String[]args)
throws Exception
{
System.out.print("7.22-7.0=" + (7.22f-7.0f));
}
}
我们可能会想当然地认为输出结果应该是 0.22 ,实际结果却是 0.21999979 !
因此,在编程中应尽量避免做浮点数的比较,否则可能会导致一些潜在的问题!
除了这些,还应注意浮点数中的一些特殊值,如 NaN、+0、-0、+无穷、-无穷等,IEEE754虽然对此做了一些约定,但各具体实现、不同的硬件结构,也会有一些差异,如果不注意也会造成错误!
四、总结:
从上面的分析,我们可以得出以下结论:
1、浮点数存在误差问题;
2、对货币等对精度敏感的数据,应该用定点数表示或存储;
3、编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较;
4、要注意浮点数中一些特殊值的处理。
本文来源于:http://blog.163.com/bbluesnow@126/blog/static/27784545201241610615201/
相关推荐
MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型。 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形式保存数值。 float,double类型是可以存浮点数...
在本文中,我们将对 Java 数据类型和 MySql 数据类型进行对应一览,帮助开发者更好地理解和使用这两种类型。 字符串类型 在 Java 中,字符串类型对应的是 java.lang.String 类型。在 MySql 中,字符串类型对应的是...
在 Java 中,对应 MySQL 的数值类型可以使用基本数据类型,例如 int、long、float 和 double 等。对应日期时间类型可以使用 java.util.Date 和 java.sql.Date 等。对应字符串类型可以使用 String 等。 理解 MySQL ...
在 Java 编程中,了解 Java 数据类型和 MySql 数据类型的对应关系非常重要。这是因为在 Java 应用程序中,我们经常需要与数据库进行交互,而 MySql 是一种常用的关系数据库管理系统。在本文中,我们将详细介绍 Java ...
本文将详细介绍MySQL中的各种数据类型及其在Java中的对应类型,并解释这些类型的具体含义以及它们在实际应用中的作用。 #### 数据类型对照表解析 ##### 1. VARCHAR (可变长度字符串) **显示长度:** L+N **数据库...
Java 和 MySQL 数据类型之间的对比是理解数据库操作和应用程序开发中数据处理的关键。这两种语言的数据类型在功能和使用上都有所不同,尽管它们都用于存储和处理数据,但各自有着特定的适用场景和特点。 首先,Java...
此外,Java的浮点数类型(float和double)对应MySQL的FLOAT和DOUBLE,而在Oracle中,可以使用BINARY_FLOAT和BINARY_DOUBLE。 Oracle数据库提供了更多的复杂数据类型,如OBJECT、ARRAY、REF,这些在Java中可以通过...
下面将详细解析MySQL中常用的各类数据类型,包括它们的大小、范围、格式以及具体用途。 ### 整型数据类型 #### TINYINT - **大小**:1字节 - **范围(无符号)**:0至255 - **用途**:适用于存储小整数值,如状态...
MySQL 数据类型是指在 MySQL 中存储数据的格式,包括整型、浮点型、定点型、字符串、日期时间型、枚举型等多种类型。下面将对 MySQL 数据类型进行详细的介绍。 整型 MySQL 中的整型包括 tinyint、smallint、...
MySQL 数据类型是指在 MySQL 数据库中存储数据的方式,它决定了数据的存储格式、大小和范围。了解 MySQL 数据类型非常重要,因为它直接影响数据库的性能、可维护性和安全性。本篇文章将详细介绍 MySQL 的所有数据...
本文将详细介绍MySQL中的主要数据类型,并通过与Oracle数据类型的对比,帮助读者更好地理解和应用这些类型。 #### 二、MySQL数据类型详解 MySQL的数据类型大致可以分为四类:数值类型、字符串类型、日期/时间类型...
MySQL 数据类型是数据库设计的基础,理解不同类型的作用和特性对于创建高效、精确的数据库至关重要。本文将详细介绍MySQL中的数据类型,主要包括数值类型、字符串类型和时间日期类型。 1、数值类型 MySQL 中的数值...
MySQL 数据类型是 MySQL 中最基本的组成部分,也是 MySQL 的核心组成部分。 MySQL 数据类型主要有六大类,即整型、浮点型、定点数浮点型、字符串、日期时间类型和二进制数据类型。 整型 整型是 MySQL 中最基本的...
以下是MySQL中一些主要的基本数据类型的详细说明: 1. **SMALLINT**: 这是一种整数类型,占用2个字节,可以存储从-32,768到32,767的整数值,适用于存储相对较小的整数,如年纪、数量等。 2. **INT**: INT是另一种...
在Java和MySQL中,处理小数时需要注意一系列与精度、数据类型选择以及运算准确性相关的问题。首先,让我们深入了解Java中小数的保存方式。 Java提供了两种基本的小数数据类型:float和double。float占用4个字节,...
在MySQL中定义数据类型具有重要的作用: 1. 对数据进行分类:数据类型有助于对数据进行归类处理,例如整数、字符串、日期等。不同的数据类型执行不同的操作,比如字符串类型可以包含文本,而整数类型只能包含数字。...
MySQL中数据类型的选择对于数据库设计至关重要,它直接关系到数据存储的有效性和查询的效率。MySQL支持多种数据类型,可以分为几大类:数值型、日期时间型、字符型以及其他数据类型等。 数值型数据类型主要包括:...
MySQL 数值型数据类型是 MySQL 中最基本和最常用的数据类型之一。该类型主要包括整型、小数和位类型。在本文中,我们将详细介绍 MySQL 数值型数据类型的概念、分类和使用方法。 一、整型 整型是 MySQL 中最基本的...