首页 > 其他分享 >Decimal中Scale和Precision是什么

Decimal中Scale和Precision是什么

时间:2023-06-15 15:02:21浏览次数:33  
标签:insert Scale Decimal Precision sec mysql test into row

Precision (field length)         精度(字段长度) 

Scale (decimal places)         范围(小数位数)
例如:-4.75, precision=3,scale=2,和符号位无关


详解


MySQL要求精度大于等于范围:

mysql> create table test (a decimal(1,3));
ERROR 1427 (42000): For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'a').


a的定义如下:

create table test (a decimal(3,1));

a字段长度为3,小数点位数为1,表示范围为99.9 ~ -99.9。如果插入的数据小数点位数比scale大,则对scale+1位置的小数进行四舍五入。例如:99.94存储为99.9,99.95提示溢出,99.949存储为99.9(注意,不是这样的四舍五入逻辑哦:99.949=>99.95=>100.0。只看scale后面的一位。)



看一些例子,加深印象:

mysql> create table test (a decimal(3,3));
Query OK, 0 rows affected (0.04 sec)
mysql> insert into test values (11);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (1);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (0.999);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values (0.9999);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (0.0004);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into test values (0.0005);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from test;
Field   1:  `a`
Catalog:    `def`
Database:   `test`
Table:      `test`
Org_table:  `test`
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     5
Max_length: 5
Decimals:   3
Flags:      NUM


+-------+
| a     |
+-------+
| 0.999 |
| 0.000 |
| 0.001 |
+-------+
3 rows in set (0.00 sec)






mysql> drop table test;
Query OK, 0 rows affected (0.00 sec)
mysql> create table test (a decimal(3,0));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test values (-999.3);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into test values (-999.7);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (1999);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (1.0);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values (1.3);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> insert into test values (-1.3);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> insert into test values (-9.3);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> insert into test values (-0.3);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select * from test;
Field   1:  `a`
Catalog:    `def`
Database:   `test`
Table:      `test`
Org_table:  `test`
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     4
Max_length: 4
Decimals:   0
Flags:      NUM




+------+
| a    |
+------+
| -999 |
|    1 |
|    1 |
|   -1 |
|   -9 |
|    0 |
+------+
6 rows in set (0.00 sec)






mysql> drop table test;
Query OK, 0 rows affected (0.01 sec)
mysql> create table test (a decimal(3,1));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into test values (1.3);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test values (99.99);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (99.9);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test values (-99.9);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test values (-99.99);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (-99.95);
ERROR 1264 (22003): Out of range value for column 'a' at row 1
mysql> insert into test values (-99.949);
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> insert into test values (-99.94);
Query OK, 1 row affected, 1 warning (0.00 sec)


mysql> select * from test;
Field   1:  `a`
Catalog:    `def`
Database:   `test`
Table:      `test`
Org_table:  `test`
Type:       NEWDECIMAL
Collation:  binary (63)
Length:     5
Max_length: 5
Decimals:   1
Flags:      NUM




+-------+
| a     |
+-------+
|   1.3 |
|  99.9 |
| -99.9 |
| -99.9 |
| -99.9 |
+-------+
5 rows in set (0.00 sec)




顺便提一句关于Result Meta的length计算:

对于decimal来说,scale和precision相等的情况下,整数部分的0要占一位length;scale为0的情况下没有小数点,length会少占一位。再考虑到unsigned,如果是无符号数,则length的计算中还不需要考虑符号位,又可以少占一位。为了处理这些逻辑,MySQL对应代码如下:

inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
                                                           uint8 scale,
                                                           bool unsigned_flag)
{
  /*
    When precision is 0 it means that original length was also 0. Thus
    unsigned_flag is ignored in this case.
  */
  DBUG_ASSERT(precision || !scale);
  return (uint32)(precision + (scale > 0 ? 1 : 0) +
                  (unsigned_flag || !precision ? 0 : 1));
}



看一个数字-4.75来理解上面的逻辑, -4.75, precision=3,scale=2,unsigned_flag=0,则上面的表达式分解如下:

precison算4、7、5三个数字,(scale > 0 ? 1 : 0)算小数点,(unsigned_flag ? 0 : 1)算符号位;根据上面代码中的注释,(!precision ? 0 : 1)表示数值0的情况,此时忽略符号位,也就是说,即使unsigned_flag=1,只要precision为0的话,负号所占的那一位总是不算,-0总是记作0。


标签:insert,Scale,Decimal,Precision,sec,mysql,test,into,row
From: https://blog.51cto.com/u_16162111/6492548

相关文章

  • container scale up/ down 原理 in kubernetes
    https://imroc.cc/kubernetes/best-practices/autoscaling/hpa-velocity.html 原理与误区HPA在进行扩缩容时,先是由固定的算法计算出期望副本数: 期望副本数=ceil[当前副本数*(当前指标/期望指标)]其中 当前指标/期望指标 的比例如果接近1(在容忍度范围内,默......
  • Java8 Stream List Map:Stream 流对象汇总 求和 某个属性 BigDecimal MDouble
    测试实体(数字对象使用MDouble):importcom.mchweb.common.lang.MDouble;importlombok.*;@Getter@Setter@Builder(toBuilder=true)@NoArgsConstructor@AllArgsConstructorpublicclassUser{privateMDoublemoney;}importcom.mchweb.common.lang.MDouble;imp......
  • 告警:线上慎用 BigDecimal !
    来源:cnblogs.com/zhangyinhua/p/11545305.html一、BigDecimal概述Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些......
  • Runtime - 运行时环境类(JVM)和大数值运算(BigInteger、BigDecimal)
    Runtime代表Java程序的运行时环境,可以通过getRuntime方法获取当前运行时。应用程序不能自己创建Runtime对象,可以通过Runtime的静态方法getRuntime()获得Runtime对象。Runtime类可以访问jvm的相关信息1、处理器数量runtime.availableProcessors()2、内存信息"获取最大内存数"--》......
  • BigDecimal的用法
    add(BigDecimal)BigDecimal对象中的值相加,然后返回这个对象。subtract(BigDecimal)BigDecimal对象中的值相减,然后返回这个对象。multiply(BigDecimal)BigDecimal对象中的值相乘,然后返回这个对象。divide(BigDecimal)BigDecimal对象中的值相除,然后返回这个对象。abs()BigDecima......
  • 【刨根问底】BigDecimal 案例和部分源码分析
    本文总以下几个部分:前言Bigdecimal定义Bigdecimal创建方式Bigdecimal部分源码分析Bigdecimal坑Bigdecimal使用建议Bigdecimal工具类前言在咱们开发过程中很容易遇到计算的问题,普通计算其实也还好使用int、long、double、float基本上能应付。但是如果涉及到数据类型转后在处理等......
  • python tkinter scale 滑动选择刻度条
    tkinter.Scale(d_f,from_=0,to=20,tickinterval=5,orient="horizontal")1.参数汇总归纳总结Scale组件中一些常用的参数以及用法。 2.方法汇总coords(value=None)获得当前滑块的位置对应Scale组件左上角的相对坐标如果设置value参数,则返回当滑块所在该位置......
  • java精确除法运算-BigDecimal
    一、BigDecimal介绍Java中提供了大数字(超过16位有效位)的操作类,即java.math.BinInteger类和java.math.BigDecimal类,用于高精度计算.其中BigInteger类是针对大整数的处理类,而BigDecimal类则是针对大小数的处理类.BigDecimal类的实现用到了BigInteger类,不......
  • delphi xe10 提示没有定义DecimalSeparator 的 解决方法
    delphi xe10提示没有定义DecimalSeparator的解决方法只需要把DecimalSeparator前加上FormatSettings变成 FormatSettings.DecimalSeparator;如果提示没有定义ShortTimeFormat,DateSeparator,ThousandSeparator,CurrencyString等等;方法同上。......
  • vue系列---【vue 使用decimal.js 解决小数相加合计精确度丢失问题】
    使用npm安装decimal.js库npminstalldecimal.js2.在Vue组件中引入该库importDecimalfrom'decimal.js';3.使用示例footerMethod({columns,data}){letsumArr=[];columns.map((column,columnIndex)=>{if(columnIndex===0){su......