首页 > 其他分享 >[转帖]NUMBER长度的误解

[转帖]NUMBER长度的误解

时间:2024-02-14 16:44:41浏览次数:27  
标签:10 38 有效数字 误解 NUMBER 转帖 SQL Oracle

https://cloud.tencent.com/developer/article/1615838

 

我们看下官方文档对NUMBER类型的介绍,

The NUMBER data type stores zero as well as positive and negative fixed numbers with absolute values from 1.0 x 10-130 to but not including 1.0 x 10126. If you specify an arithmetic expression whose value has an absolute value greater than or equal to 1.0 x 10126, then Oracle returns an error. Each NUMBER value requires from 1 to 22 bytes. The precision p can range from 1 to 38. A NUMBER value requires from 1 to 22 bytes.

NUMBER类型是Oracle的一种变长数值类型,他的取值范围是10^(-130)-10^126(不包括),精度是38位,存储空间是1-22字节。

轻描淡写,说了好几个数字,虽然很多人都知道这个NUMBER类型,但是这些数字,就未必能一下就能说清楚。

1. 精度是38,是说允许38个数字?

NUMBER类型的定义格式,NUMBER(P,S),其中P是Precison的英文缩写,即精度缩写,表示有效数字的位数。S是Scale的英文缩写,表示从小数点到最低有效数字的位数,他为负数时,表示从最大有效数字到小数点的位数。

因此精度38,表示的是最多不能超过38个有效数字,如果超过了,就会提示错误,如下所示,

SQL> create table t (id number(39));
create table t (id number(39))
                            *
ERROR at line 1:
ORA-01727: numeric precision specifier is out of range (1 to 38)

如果字段定义的时候未指定精度,则默认是22,

SQL> create table t (id number);
Table Created.


SQL> SELECT table_name, column_name, data_type, data_length 
     FROM user_tab_columns WHERE table_name='TT';
TABLE_NAME COLUMN_NAM DATA_TYPE  DATA_LENGTH
---------- ---------- ---------- -----------
        T         ID    NUMBER           22

精度(p)和刻度(s)遵循以下规则:

  • 当一个数的整数部分的长度 > p-s 时,Oracle就会报错
  • 当一个数的小数部分的长度 > s 时,Oracle就会舍入。
  • 当s(scale)为负数时,Oracle就对小数点左边的s个数字进行舍入。
  • 当s > p 时, p表示小数点后第s位向左最多可以有多少位数字,如果大于p则Oracle报错,小数点后s位向右的数字被舍入

但是有个奇怪的现象,向表插入如下的数据,设置显示格式,

SQL> create table t (id number(38));
Table Created.




SQL> col id for 99999999999.9999999999999999999999999999999999999;


SQL> insert into t values(12.12345678912345678912345678912345678912,'');
1 row created.


SQL> select * from test;
                                        ID
-------------------------------------------
   12.123456789123456789123456789123456789  - 38位有效数字

但是改下显示的格式,发现有效数字,就是40个,超过了定义精度,难道存在bug?

SQL> col id  for 999999999999.99999999999999999999999999999999999999999
SQL> select * from t;
                                              ID
--------------------------------------------------
     12.12345678912345678912345678912345678912000

官方文档,给出了这个解释,p是精度,或是有效十进制数的总位数,最大的有效数字是最左边的非零数字,而最小有效位是最右边的数字。Oracle保证数字的可移植性,精度高达20 base-100 digits,相当于39位或40位十进制数字,取决于小数点的位置,因此上述例子中,40个有效数字,其实是合理的,

p is the precision, or the maximum number of significant decimal digits, where the most significant digit is the left-most nonzero digit, and the least significant digit is the right-most known digit. Oracle guarantees the portability of numbers with precision of up to 20 base-100 digits, which is equivalent to 39 or 40 decimal digits depending on the position of the decimal point.

2.取值范围是10^(-130)-10^126(不包括)

可以看到,当插入10^126的数据时,就会提示溢出,这是能存入NUMBER类型字段的正数最大值,

SQL> insert into t values(1e+125);
1 row created.


SQL> insert into t values(1e+126);
insert into t values(1e+126)
                      *
ERROR at line 1:
ORA-01426: numeric overflow

因为最大值是10^126(不包括),相当于<10^126,最近的值就是9.9...9 * 10^125,即38个9后边带88个0。

针对这个问题,“Oracle中NUMBER最大长度是多少?”,他的迷惑性,就在于对他和字符串类型的惯性思维。因为字符串类型,VARCHAR2(X),X就是字符个数,而NUMBER(X),X是精度,X是5,未必就是5个数字,其实深究起来,有效位数的含义,和VARCHAR2(X)中的X是相近的,只是除了有效位数外,还可以用0补位,数字个数,就会超过X。准确地说,NUMBER取值范围就是10^(-130)-10^126(不包括)。

标签:10,38,有效数字,误解,NUMBER,转帖,SQL,Oracle
From: https://www.cnblogs.com/jinanxiaolaohu/p/17984225

相关文章

  • [转帖]Oracle number类型详解
    Oraclenumber类型详解简介基本说明容易出错情况Number与MySQL数据类型简介Oracle的number类型比较复杂,很多限制,但是掌握一点小技巧就能轻松搞定。基本说明number(precision,scale)precision表示数字中的有效位,从左边第一个不为0的数算起,小数点和负号不计入有效......
  • [转帖]linux参数之max_map_count
    https://www.cnblogs.com/duanxz/p/3567068.html “Thisfilecontainsthemaximumnumberofmemorymapareasaprocessmayhave.Memorymapareasareusedasaside-effectofcallingmalloc,directlybymmapandmprotect,andalsowhenloadingsharedlibr......
  • ISO8601 week number of the year
      importdatetimedatetime.date(2023,1,1).isoweekday()defleap_year(year:int)->bool:returnyear%4==0andyear%100!=0oryear%400==0foryearinrange(2001,2101):weekday=datetime.date(year,1,1).isoweekday()......
  • [转帖]二八定律、墨菲定律和阿姆达尔定律
    二八定律20%的人用脖子以上来挣钱80%的人用脖子以下赚钱20%的人正面思考着80%的人负面思考着20%的人买时间80%的人卖时间20%的人做事业80%的人做事情20%的人重视经验80%的人重视学历20%的人知道行动才有结果80%的人认为知识就是力量20%的人我要怎样做......
  • [转帖]网络知识梳理:网络广播
    网络广播是一种网络通信的形式,其中一个发送端向多个接收端同时发送相同的信息。在计算机网络中,这通常涉及到使用特定的广播地址,使得所有连接到该网络的设备都能接收到这些信息。网络广播可以根据范围和用途分为几种类型:1.广播(Broadcasting)定义:在广播中,消息被发送到网络上......
  • [转帖]Unix操作系统的前世今生
    Unix是一种多用户、多任务操作系统,最初由AT&T贝尔实验室的肯·汤普逊(KenThompson)和丹尼斯·里奇(DennisRitchie)等人开发于上世纪70年代初。它被设计成一种通用的操作系统,支持跨多种硬件平台,并提供了许多先进的特性,如多任务处理、分时处理、多用户能力和可移植性。Unix的......
  • less报错,Error evaluating function `unit`: the first argument to unit must be a n
    1、less-loader版本太高了,可以降低版本2、lessc的执行参数里面增加一个参数--math=always3、可以关闭严格模式{loader:"less-loader",options:{lessOptions:{strictMath:false,},},}, 4、vite配置可以设置math:"always",......
  • 【转帖】就是要你懂抓包--WireShark之命令行版tshark
    plantegg.github.io/2019/06/21/就是要你懂抓包--WireShark之命令行版tshark/ 玩转TShark(Wireshark的命令行版)在我感叹Wireshark图形界面的强大时候,有时候也抱怨有点慢,或者感叹下要是有命令行界面版该多好啊,实际上TShark就是WireShark的命令行版,WireShark的功能基本都有,还......
  • Trygub Number
    参考资料做「NOI2017」整数的时候了解到有这个东西,支持对于\(B\)进制数\(X\):加上\(x\cdotB^y\),复杂度为\(\mathcal{O}(\logV+\logn)\)。查询第\(k\)位的值,复杂度为\(\mathcal{O}(\logV+\logn)\)。复杂度是瞎写的,反正就是一个\(\log\)。具体思路是维护一个......
  • 【转帖】基础软件开发 -- 神秘的MESI和坑爹的LockFree
    https://zhuanlan.zhihu.com/p/681321783 又开新坑,继续掰扯基础软件开发。这里已经更新到第二季了,欲先睹为快的可以到这里:基础软件开发新坑--神秘的MESI和坑爹的LockFree(一)基础软件开发新坑--神秘的MESI和坑爹的LockFree(二)正文开始:在《HPC(高性能计算第一篇):一文......