MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景
MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型。
其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形式保存数值。
float,double类型是可以存浮点数(即小数类型),但是float有个坏处,当你给定的数据是整数的时候,那么它就以整数给你处理。这样我们在存取货币值的时候自然遇到问题,我的default值为:0.00而实际存储是0,同样我存取货币为12.00,实际存储是12。
幸好mysql提供了两个数据类型:decimal,这种数据类型可以轻松解决上面的问题:decimal类型被 MySQL 以同样的类型实现,这在 SQL92 标准中是允许的。他们用于保存对准确精度有重要要求的值,例如与金钱有关的数据。
数据定义
float(M,S) M为全长,S为小数点后长度。
数据库类型和Java类型之间的关系:
DBC Type Java Type
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
BOOLEAN boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
CLOB Clob
BLOB Blob
ARRAY Array
DISTINCT mapping of underlying type
STRUCT Struct
REF Ref
项目中BigDecimal与Double使用场景
金额要用BigDecimal
金额计算不能用doube!!!!
金额计算必须用BigDecimal,下面对比一下用double 跟BigDecimal的区别。先看一个小例子:
请看题:

示例1
问, 结果是多少? 0.01?
No! 结果是0.009999999999999998!
为什么会这样呢? 因为float和double都是浮点数, 都有取值范围, 都有精度范围. 浮点数与通常使用的小数不同, 使用中, 往往难以确定.
常见的问题是定义了一个浮点数, 经过一系列的计算, 它本来应该等于某个确定值, 但实际上并不是!
double相减会转换成二进制,因double有效位数为 16位这就会出现存储小数位数不够的情况,这种情况下就会出现误差,解决方法就是使用BigDecimal,它的有效长度足够长可存储小数位数。
因此可代替double来进行加减乘除, 金额必须是完全精确的计算, 故不能使用double或者float, 而应该采用java.math.BigDecimal.
加减乘除
两个BigDecimal值应该怎样进行加减乘除呢? +, -, *, / 这样写吗? 不!
请看示例:

加减乘除使用了英文的加减乘除, 即add, substract, multiply和divide
大小比较
两个BigDecimal值怎么比较大小呢? 能用>或者<吗? 也不可以!

两个BigDecimal值比较使用compareTo方法, 比较结果有-1, 0, 1, 分别表示小于, 等于, 大于; 对于0, 可以使用BigDecimal.ZERO表示!
四舍五入

简化BigDecimal计算的小工具类
如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。
你能够忍受这么烦琐的过程吗?
网上提供的工具类Arith来简化操作。它提供以下静态方法,包括加减乘除和四舍五入:
public static double add(double v1,double v2)
public static double sub(double v1,double v2)
public static double mul(double v1,double v2)
public static double div(double v1,double v2)
public static double div(double v1,double v2,int scale)
public static double round(double v,int scale)
定点数和浮点数的区别
在计算机系统的发展过程中,曾经提出过多种方法表达实数。典型的比如相对于浮点数的定点数(Fixed Point Number)。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。
货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。
SQL 中的 NUMBER 数据类型就是利用定点数来定义的。还有一种提议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。
定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。
最终,绝大多数现代的计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。
比如 123.45 用十进制科学计数法可以表达为 1.2345 × 102 ,其中 1.2345 为尾数,10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。
在MySQL中使用浮点数类型和定点数类型来表示小数。浮点数类型包括单精度浮点数(FLOAT型)和双精度浮点数(DOUBLE型)。定点数类型就是DECIMAL型。MySQL的浮点数类型和定点数类型如下表所示:
| 类型名称 | 字节数 | 负数的取值范围 | 非负数的取值范围 |
|---|---|---|---|
| FLOAT | 4 | -3.402823466E+38~ -1.175494351E-38 |
0和1.175494351E-38~ 3.402823466E+38 |
| DOUBLE | 8 | -1.7976931348623157E+308~ -2.2250738585072014E-308 |
0和2.2250738585072014E-308~ 1.7976931348623157E+308 |
| DECIMAL(M,D)或DEC(M,D) | M+2 | 同DOUBLE型 | 同DOUBLE型 |
从上表中可以看出,DECIMAL型的取值范围与DOUBLE相同。但是,DECIMAL的有效取值范围由M和D决定,而且DECIMAL型的字节数是M+2,也就是说,定点数的存储空间是根据其精度决定的。
MySQL
BigDecimal在进行入库时, 数据库选择decimal类型, 长度可以自定义, 如18; 小数点我们项目中用的是2, 保留2位小数. 此外还要注意的就是默认值, 一定写成0.00, 不要用默认的NULL, 否则在进行加减排序等操作时, 会带来转换的麻烦!
`balance` decimal(18,2) DEFAULT '0.00' COMMENT '账户余额',
MySQL DECIMAL数据类型用于在数据库中存储精确的数值。我们经常将DECIMAL数据类型用于保留准确精确度的列,例如会计系统中的货币数据。
要定义数据类型为DECIMAL的列,请使用以下语法:
|
1
|
column_name DECIMAL(P,D); |
在上面的语法中:
P是表示有效数字数的精度。P范围为1〜65。D是表示小数点后的位数。D的范围是0~30。MySQL要求D小于或等于(<=)P。
DECIMAL(P,D)表示列可以存储D位小数的P位数。十进制列的实际范围取决于精度和刻度。
与INT数据类型一样,DECIMAL类型也具有UNSIGNED和ZEROFILL属性。 如果使用UNSIGNED属性,则DECIMAL UNSIGNED的列将不接受负值。
如果使用ZEROFILL,MySQL将把显示值填充到0以显示由列定义指定的宽度。 另外,如果我们对DECIMAL列使用ZERO FILL,MySQL将自动将UNSIGNED属性添加到列。
以下示例使用DECIMAL数据类型定义的一个叫作amount的列。
|
1
|
amount DECIMAL(6,2); |
在此示例中,amount列最多可以存储6位数字,小数位数为2位; 因此,amount列的范围是从-9999.99到9999.99。
参考:
https://www.jb51.net/article/109363.htm
https://www.cnblogs.com/owenma/p/7991508.html
http://www.cnblogs.com/owenma/p/7097602.html
MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景的更多相关文章
- MySQL中Decimal类型和Float Double等区别
MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...
- mysql中Numeric类型和int类型的区别
首先记一下,Numeric数字数据只包含 数字.数字数据包括正数.负数.小数.分数和整数 例子如下: Numeric(6,2) Numeric(16,6) Numeric(16,0) 从左到右,第一个 ...
- Mysql 中 text类型和 blog类型的异同
MySQL存在text和blob: (1)相同 在TEXT或BLOB列的存储或检索过程中,不存在大小写转换,当未运行在严格模式时,如果你为BLOB或TEXT列分配一个超过该列类型的最大长度的值值,值被 ...
- mysql中varchar类型和datetime类型字段进行比较
我是在mysql5.7版本进行比较 表a的字段order_no和表iwebshop_tmp的字段order_no一样 需要更新iwebshop_member_order表的datetime类型expi ...
- MySQL中 DECIMAL FLOAT DOUBLE的区别
第一篇文章: MySQL中Decimal类型和Float Double等区别 MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,d ...
- Python3.x中bytes类型和str类型深入分析
Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和b ...
- 关于 Go 中 Map 类型和 Slice 类型的传递
关于 Go 中 Map 类型和 Slice 类型的传递 Map 类型 先看例子 m1: func main() { m := make(map[int]int) mdMap(m) fmt.Printl ...
- java 8 Stream中操作类型和peek的使用
目录 简介 中间操作和终止操作 peek 结论 java 8 Stream中操作类型和peek的使用 简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作.这两种有什么区别呢 ...
- Java中的基本类型和引用类型变量的区别
Java中的基本类型和引用类型变量的区别 学了一年多,说实话你要我说这些东西我是真说不出来是啥意思 基本类型: 基本类型自然不用说了,它的值就是一个数字,一个字符或一个布尔值. 引用类型: ...
随机推荐
- linux----------linux下安装rar和unrar命令
1.wget http://www.rarlab.com/rar/rarlinux-x64-4.2.0.tar.gz 2.tar xf rarlinux-x64-4.2.0.tar.gz 解压下 ...
- Java面试宝典(2018版)
置顶 2018年11月10日 23:49:18 我要取一个响亮的昵称 阅读数:8893 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/chen ...
- js 闭包,作用域,this 终结篇(转)
之前有写过闭包,作用域,this方面的文章,但现在想想当时写的真是废话太多了,以至于绕来绕去的,让新手反而更难理解了,所以就有了此篇文章,也好和闭包,作用域,this告一段落. 第一个问题:什么是闭包 ...
- Linux 命令整理-ps
ps 命令 ps -ef | grep tomcat ps -ef :以长格式(全格式)显示所有进程:“|” :是管道grep :检索tomcat :与字符tomcat有关的进程 ps[选项]-e:显 ...
- oracle之数据恢复(delete误删)
ALTER TABLE TA_申请材料表 ENABLE row movement ; flashback table TA_申请材料表 to timestamp to_timestamp('2019- ...
- dataguard日志自动删除
dataguard日志自动删除 1.判断日志是否已经应用到今天.2.删除3天前的日志.3.主机.备机分别配置 ----check_del_arch.sh#!/bin/shORACLE_HOME=/ho ...
- 2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解 实验1-1直接修改程序机器指令,改变程序执行流程 先输入objdump -d 20165305pwn2查看反汇编代码 ...
- DBDocumentGenerator使用
报错1:未能成功安装.NET Framework 3.5(包括.NET2.0和3.0) 解决办法:安装离线包. ( 1.将“sxs”文件复制到C盘,用完后可以删除:2.右键以管理员身份运行NET Fr ...
- DUILIB消息处理过程
DUILIB消息处理机制 方法一. 首先窗口基类创建 CWindowWnd->Create() 调用 CWindowWnd->RegisterWindowClass() 注册 CWindo ...
- vue 3.0的搭建
1. 删除以前的vue 2.x版本,并下载3.x版本 npm uninstall -g vue-cli / yarn global remove vue-cli npm install -g @vue ...