当前位置:嗨网首页>书籍在线阅读

05-日期类型选择

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

浮点数一般用于表示含有小数部分的数值。当一个字段被定义为浮点类型后,如果插入数据的精度超过该列定义的实际精度,则插入值会被四舍五入到实际定义的精度值,然后插入,四舍五入的过程不会报错。在MySQL中float、double(或real)用来表示浮点数。

定点数不同于浮点数,定点数实际上是以字符串形式存放的,所以定点数可以更精确地保存数据。如果实际插入的数值精度大于实际定义的精度,则 MySQL 会进行警告(默认的SQLMode下),但是数据按照实际精度四舍五入后插入;如果SQLMode是在TRADITIONAL (传统模式)下,则系统会直接报错,导致数据无法插入。在MySQL中,decimal(或numberic)用来表示定点数。

在简单了解了浮点数和定点数的区别之后,来看一个例子,回顾一下前面讲到的浮点数精确性问题。

mysql> create table t (f float( 8,1));

Query OK, 0 rows affected (0.03 sec)

mysql> desc t;

+-------+------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+------------+------+-----+---------+-------+

| f | float(8,1) | YES | | NULL | |

+-------+------------+------+-----+---------+-------+

1 row in set (0.00 sec)

mysql> insert into t values (1.23456);

Query OK, 1 row affected (0.00 sec)

mysql> select * from t;

+------+

| f|

+------+

| 1.2 |

+------+

1 row in set (0.00 sec)

mysql> insert into t values (1.25456);

Query OK, 1 row affected (0.00 sec)

mysql> select * from t;

+------+

| f |

+------+

| 1.2 |

| 1.3 |

+------+

2 rows in set (0.00 sec)

从上面的例子中,可以发现对于第一次插入值1.23456到float(8,1)时,该值被截断,并保存为1.2,而第二次插入值1.25456到float(8,1)时,该值进行了四舍五入然后被截断,并保存为1.3,所以在选择浮点型数据保存小数时,要注意四舍五入的问题,并尽量保留足够的小数位,避免存储的数据不准确。

为了能够让读者了解浮点数与定点数的区别,再来看一个例子:

mysql> CREATE TABLE test (c1 float(10,2),c2 decimal(10,2));

Query OK, 0 rows affected (0.29 sec)

mysql> insert into test values(131072.32,131072.32);

Query OK, 1 row affected (0.07 sec)

mysql> select * from test;

+-----------+-----------+

| c1 | c2|

+-----------+-----------+

| 131072.31 | 131072.32 |

+-----------+-----------+

1 row in set (0.00 sec)

从上面的例子中可以看到,c1列的值由131072.32变成了131072.31,这是上面的数值在使用单精度浮点数表示时,产生了误差。这是浮点数特有的问题。因此在精度要求比较高的应用中(比如货币)要使用定点数而不是浮点数来保存数据。

另外,浮点数的比较也是一个普遍存在的问题,下面的程序片断中对两个浮点数做减法运算:

public class Test {

public static void main(String[] args) throws Exception {

System.out.print("7.22-7.0=" + (7.22f-7.0f));

}

}

对上面Java程序的输出结果可能会想当然地认为是0.22,但是,实际结果却是7.22-7.0=0.21999979,因此,在编程中应尽量避免浮点数的比较,如果非要使用浮点数的比较则最好使用范围比较而不要使用“==”比较。

下面使用定点数来实现上面的例子:

import java.math.BigDecimal;

/*

  • 提供精确的减法运算。

  • @param v1

  • @param v2

*/

public class Test {

public static void main(String[] args) throws Exception {

System.out.print("7.22-7.0=" + subtract(7.22,7.0));

}

public static double subtract(double v1, double v2) {

BigDecimal b1 = new BigDecimal(Double.toString(v1));

BigDecimal b2 = new BigDecimal(Double.toString(v2));

return b1.subtract(b2).doubleValue();

}

}

上面的实例使用Java的BigDecimal类实现了定点数的精确计算,所以7.22减7.0的结果和预想的相同,为7.22-7.0=0.22。

注意:在今后关于浮点数和定点数的应用中,用户要考虑到以下几个原则:

浮点数存在误差问题;

对货币等对精度敏感的数据,应该用定点数表示或存储;

在编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较;

要注意浮点数中一些特殊值的处理。