MySQL中Decimal类型和FloatDouble的区别BigDecimal与
Doub。。。
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来简化操作。它提供以下静态⽅法,包括加减乘除和四舍五⼊:
bigdecimal取值范围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的浮点数类型和定点数类型如下表所⽰:
类型名称字节数负数的取值范围⾮负数的取值范围
FLOAT4-3.402823466E+38~
-1.175494351E-38
0和1.175494351E-38~
3.402823466E+38
DOUBLE8-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的列,请使⽤以下语法:
1column_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的列。
1amount DECIMAL(6,2);
在此⽰例中,amount列最多可以存储6位数字,⼩数位数为2位; 因此,amount列的范围是从-9999.99到9999.99。
参考:
www.jb51/article/109363.htm
wwwblogs/owenma/p/7991508.html
wwwblogs/owenma/p/7097602.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论