一、场景:从数据表中读出Decimal类型的数据直接塞给Double类型的对象时,并不会有什么异常。

如果要再此基础上计算,就会发生异常。

比如:读出数据为0.0092,将其乘以100,则变成了0.919999999999999...

二、原因:

java mysql 数据类型对照如下:

类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述
           
VARCHAR L+N VARCHAR java.lang.String 12  
CHAR N CHAR java.lang.String 1  
BLOB L+N BLOB java.lang.byte[] -4  
TEXT 65535 VARCHAR java.lang.String -1  
           
INTEGER 4 INTEGER UNSIGNED java.lang.Long 4  
TINYINT 3 TINYINT UNSIGNED java.lang.Integer -6  
SMALLINT 5 SMALLINT UNSIGNED java.lang.Integer 5  
MEDIUMINT 8 MEDIUMINT UNSIGNED java.lang.Integer 4  
BIT 1 BIT java.lang.Boolean -7  
BIGINT 20 BIGINT UNSIGNED java.math.BigInteger -5  
FLOAT 4+8 FLOAT java.lang.Float 7  
DOUBLE 22 DOUBLE java.lang.Double 8  
DECIMAL 11 DECIMAL java.math.BigDecimal 3  
BOOLEAN 1 同TINYINT      
           
ID 11 PK (INTEGER UNSIGNED) java.lang.Long 4  
           
DATE 10 DATE java.sql.Date 91  
TIME 8 TIME java.sql.Time 92  
DATETIME 19 DATETIME java.sql.Timestamp 93  
TIMESTAMP 19 TIMESTAMP java.sql.Timestamp 93  
YEAR 4 YEAR java.sql.Date 91

三、解决方案:

1、将double类型重新变成BigDecimal类型,最后的结果还要获取有效位数

double d = 111231.5585;

BigDecimal b = new BigDecimal(f);

double df = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

2、因为数据表里的类型是Decimal,所以讲java对象中对应的成员变量的类型改成BigDecimal即可。

四、BigDecimal简介

在mysql中,对于精度比较高的数据存储,比如money,需要用decimal类型,而不会采用float或double类型,原因在于后者数据误差较大。

decimal列的声明语法是decimal(m,d)。

在mysql 5.1中,参数的取值范围:

1、M是数字的最大数(精度)。其范围为1~65(在较旧的MySQL版本中,允许的范围是1~254)。

2、D是小数点右侧数字的数目(标度)。其范围是0~30,但不得超过M。 
说明:float占4个字节,double占8个字节,decimail(M,D)占M+2个字节。 
如DECIMAL(5, 2) 的最大值为9 9 9 9 . 9 9,因为有7 个字节可用。 
 
注: 
M 与D 对DECIMAL(M, D) 取值范围的影响 
 

类型说明 取值范围(MySQL < 3.23) 取值范围(MySQL >= 3.23) 
DECIMAL(4, 1) -9.9 到 99.9 -999.9 到 9999.9 
DECIMAL(5, 1) -99.9 到 999.9 -9999.9 到 99999.9 
DECIMAL(6, 1) -999.9 到 9999.9 -99999.9 到 999999.9 
DECIMAL(6, 2) -99.99 到 999.99 -9999.99 到 99999.99 
DECIMAL(6, 3) -9.999 到 99.999 -999.999 到 9999.999
 

# 在mysql 3.23 及以后的版本中,decimal(m, d) 的取值范围等于早期版本中的decimal(m + 2, d) 的取值范围。 
 
另外一种数据类型:
LongBlob,这种数据类型可以直接把图像文件存到数据表中! 
 
在研究mysql的decimal数据类型,现把数据实验结果公布: 
数据库版本:Server version: 5.0.45 Source distribution 
 
1、创建表结构

create table ta (a float,b decimal(10,5));
 

2、插入数据

insert into ta (a,b) values(1,12345.123423);
 

实际插入的b列数据为:12345.12342

insert into ta (a,b) values(1,123456.1234);

实际插入的b列数据为:99999.99999

结论:decimal数据类型, 
1、当插入的整数部分的值超过了其表示范围后就直接忽略了小数部分的值,并以最大值填充。 
2、当整数部分合法,小数部分多余的位数,直接截断。

java中如何使用BigDecimal使得Double类型保留两位有效数字的更多相关文章

  1. java double类型保留两位小数4种方法【转】

    4种方法,都是四舍五入,例: import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberF ...

  2. java double类型保留两位小数4种方法

    http://blog.csdn.net/huaishuming/article/details/17752365 ****************************************** ...

  3. JavaScript中Float类型保留两位小数

    JavaScript中Float类型保留两位小数 核心方法: num:要操作的数字     size:要保留的位数 parseFloat(num).toFixed(size); 实现代码如下:var  ...

  4. Double 数据保留两位小数二:直接截取小数后面两位,不进行四舍五入

    package com; public class T2 { public static void main(String[] args) { System.out.println(calculate ...

  5. Double 数据保留两位小数一:五舍六入

    package com; public class T2 { public static void main(String[] args) { System.out.println(calculate ...

  6. c# double 类型保留几位小数

    C 或 c :货币 D 或 d:十进制数 E 或 e:科学记数法(指数) F 或 f:定点 G 或 g:常规 N 或 n:数字 P 或 p:百分比 double.ToString("Nx & ...

  7. Double值保留两位小数的四种方法

    public class DoubleTest { //保留两位小数第三位如果大于4会进一位(四舍五入) double f = 6.23556; /** *使用精确小数BigDecimal */ pu ...

  8. 如何把Java的double类型变量保留两位小数

    已知 双精度标量 f,  如果想以字符串形式输出,小数点后保留2位,可直接通过C语言的输出格式,System.out.printf("%.2f", f), 达到目的. 如果想要先转 ...

  9. Java-小技巧-005-double类型保留两位小数4种方法

    4种方法,都是四舍五入,例: import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberF ...

随机推荐

  1. 条目二十二《切勿修改set或multiset的键》

    条目二十二<切勿修改set或multiset的键> 所有的标准关联容器一样,set和multiset按照一定的顺序来存放自己的元素,而这些容器的正确行为也是建立在其元素保持有序的基础之上的 ...

  2. GitHub访问下载太慢解决办法

    原因 为什么慢?github的CDN被某墙屏了. 解决方法 绕过dns解析,在本地直接绑定host,该方法也可加速其他因为CDN被屏蔽导致访问慢的网站. 实现 在本地host文件中添加映射,步骤如下: ...

  3. angular5新增全局的模块

    比如新增一个全局的swiper,需要在webpack中配置: 之后在代码中就可以用了

  4. redis实现 msetex和 getdel命令

    1.redis本身不提供 msetex命令(批量增加key并设置过期时间) class RedisExtend { private static final Logger logger = Logge ...

  5. 使用webbench工具测试网站访问压力

    介绍 Webbench是一个在Linux下使用的网站压测工具.它使用fork()模拟多个客户端 同时访问我们设定的URL,测试网站在压力下工作的性能, 最多可以模拟3万个并发连接去测试网站的负载能力. ...

  6. 3.抓包神器Fiddler简介(转载)

    转自:https://www.cnblogs.com/ailiailan/p/hanxiaobei.html 使用Fiddler的两个场景,1:客户端对服务端返回数据的容错:2:服务端对异常请求数据的 ...

  7. 关于halo博客系统的使用踩坑——忘记登录密码

    踩坑: halo系统可以直接通过运行jar -jar halo-0.0.3.jar跑起来,也可以通过导入IDE然后运行Application的main方法跑起系统. h2数据库访问路径:http:// ...

  8. (转)python time模块和datetime模块详解

    python time模块和datetime模块详解 原文:http://www.cnblogs.com/tkqasn/p/6001134.html 一.time模块 time模块中时间表现的格式主要 ...

  9. java中Map转化为bean

    Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值,在java编程中会经常用到.但是当我们进行业务逻辑的处理或着操作数据库时,往往应用的是我们自己定义的的Bean或VO来传递和 ...

  10. 理解session和cookie

    Session 与 Cookie 的作用都是为了保持访问用户与后端服务器的交互状态.它们有各自的优点,也有各自的缺陷,然而具有讽刺意味的是它们的优点和它们的使用场景又是矛盾的.例如,使用 Cookie ...