Oracle NUMBER 的 Scale 为何会大于 Precision?

发布于 2024-08-25 21:58:34 字数 94 浏览 5 评论 0原文

文档指出:“精度范围可以从 1 到 38。标度范围可以从 -84 到 127”。

规模怎么可能大于精度呢? Scale 的范围不应该是 -38 到 38 吗?

The documentation states: "Precision can range from 1 to 38. Scale can range from -84 to 127".

How can the scale be larger than the precision? Shouldn't the Scale range from -38 to 38?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

几度春秋 2024-09-01 21:58:34

根据 Oracle 文档:

小数位数可以大于精度,最常见的是使用符号时(其中小数部分可能很大)。当小数位数大于精度时,精度指定小数点右侧有效数字的最大位数。例如,定义为 NUMBER(4,5) 的列要求小数点后第一位数字为零,并将所有值舍入到小数点后第五位数字之后。

我是这样看的:

  • Precision大于Scale(例如NUMBER(8,5))时,没问题,这很简单。 精度表示该数字总共有 8 位数字,其中 5 位位于小数部分 (.→),因此整数部分 (←.) 将有 3 位数字。这很容易。
  • 当您看到 Precision 小于 Scale(例如 NUMBER(2, 5))时,这意味着 3 件事:

    • 该数字不会有任何整数部分,只有小数部分。所以整数部分的0不会计入计算中,你说的是0.12345而不是0.12345。事实上,如果您在整数部分只指定 1 位数字,它总是会返回错误。
    • Scale 表示数字小数部分的总位数。在本例中为 5。因此可以是 .12345 或 .00098,但总共不超过 5 位数字。
    • 小数部分分为两部分:有效数字和零。有效数字由 Precision 指定,最小零个数等于 (Scale - Precision)。示例:

    这里数字的小数部分必须至少有 3 个零。后面跟着 2 个有效数字(也可以有一个零)。因此,3 个零 + 2 个有效数字 = 5,即 Scale 数字。

简而言之,当您看到 NUMBER(6,9) 时,这告诉我们小数部分总共有 9 位数字,以 3 个必需的零开头,后跟 6 位数字。

以下是一些示例:

SELECT CAST(.0000123 AS NUMBER(6,9)) FROM dual;   -- prints: 0.0000123; .000|012300
SELECT CAST(.000012345 AS NUMBER(6,9)) FROM dual; -- prints: 0.0000123; .000|012345
SELECT CAST(.123456 AS NUMBER(3,4)) FROM dual;    -- ERROR! must have a 1 zero (4-3=1)
SELECT CAST(.013579 AS NUMBER(3,4)) FROM dual;    -- prints: 0.0136; max 4 digits, .013579 rounded to .0136

According to Oracle Documentation:

Scale can be greater than precision, most commonly when ex notation is used (wherein decimal part can be so great). When scale is greater than precision, the precision specifies the maximum number of significant digits to the right of the decimal point. For example, a column defined as NUMBER(4,5) requires a zero for the first digit after the decimal point and rounds all values past the fifth digit after the decimal point.

Here's how I see it :

  • When Precision is greater than Scale (e.g NUMBER(8,5)), no problem, this is straightforward. Precision means the number will have a total of 8 digits, 5 of which are in the fractional part (.→), so the integer part (←.) will have 3 digits. This is easy.
  • When you see that Precision is smaller than Scale (e.g NUMBER(2, 5)), this means 3 things :

    • The number will not have any integer part, only fractional part. So the 0 in the integer part is not counted in the calculations, you say .12345 not 0.12345. In fact, if you specify just 1 digit in the integer part, it will always return an error.
    • The Scale represents the total number of digits in the fractional part that the number will have. 5 in this case. So it can be .12345 or .00098 but no more than 5 digits in total.
    • The fractional part is divided into 2 parts, significant numbers and zeros. Significant numbers are specified by Precision, and minimum number of zeros equals (Scale - Precision). Example :

    here The number will must have a minimum of 3 zeros in the fractional part. followed by 2 significant numbers (could have a zero as well). So 3 zeros + 2 significant numbers = 5 which is the Scale number.

In brief, when you see for example NUMBER(6,9), this tells us that the fractional part will have 9 digits in total, starting by an obligatory 3 zeros and followed by 6 digits.

Here are some examples :

SELECT CAST(.0000123 AS NUMBER(6,9)) FROM dual;   -- prints: 0.0000123; .000|012300
SELECT CAST(.000012345 AS NUMBER(6,9)) FROM dual; -- prints: 0.0000123; .000|012345
SELECT CAST(.123456 AS NUMBER(3,4)) FROM dual;    -- ERROR! must have a 1 zero (4-3=1)
SELECT CAST(.013579 AS NUMBER(3,4)) FROM dual;    -- prints: 0.0136; max 4 digits, .013579 rounded to .0136
机场等船 2024-09-01 21:58:34

问题可能是为什么不呢?
尝试以下 SQL。

select cast(0.0001 as number(2,5)) num, 
       to_char(cast(0.0001 as number(2,5))) cnum,
       dump(cast(0.0001 as number(2,5))) dmp
  from dual

你看到的是你可以容纳少量的数字就是这种结构
可能并不经常需要它,但我确信某个地方有人存储非常精确但非常小的数字。

The question could be why not ?
Try the following SQL.

select cast(0.0001 as number(2,5)) num, 
       to_char(cast(0.0001 as number(2,5))) cnum,
       dump(cast(0.0001 as number(2,5))) dmp
  from dual

What you see is that you can hold small numbers is that sort of structure
It might not be required very often, but I'm sure somewhere there is someone who is storing very precise but very small numbers.

天生の放荡 2024-09-01 21:58:34

Scale 大于 Precision 的情况可以这样总结:

小数点右侧的位数 = Scale

小数点右侧零的最小数量 = Scale - Precision

--this will work 
select cast(0.123456 as number(5,5)) from dual;

返回 0.12346

-- but this
select cast(0.123456 as number(2,5)) from dual;
--will return "ORA-1438 value too large".  
--It will not return err with at least 5-2 = 3 zeroes:
select cast(0.000123456 as number(2,5)) from dual;

返回 0.00012

-- and of course this will work too
select cast(0.0000123456 as number(2,5)) from dual;

返回 0.00001

The case where Scale is larger than Precision could be summarized this way:

Number of digits on the right of decimal point = Scale

Minimum number of zeroes right of decimal = Scale - Precision

--this will work 
select cast(0.123456 as number(5,5)) from dual;

returns 0.12346

-- but this
select cast(0.123456 as number(2,5)) from dual;
--will return "ORA-1438 value too large".  
--It will not return err with at least 5-2 = 3 zeroes:
select cast(0.000123456 as number(2,5)) from dual;

returns 0.00012

-- and of course this will work too
select cast(0.0000123456 as number(2,5)) from dual;

returning 0.00001

來不及說愛妳 2024-09-01 21:58:34

感谢大家的回答。看起来精度就是有效位数。

 select cast(0.000123 as number(2,5)) from dual

结果为:

.00012

其中

 select cast(0.00123 as number(2,5)) from dual

 select cast(0.000999 as number(2,5)) from dual

都导致:

ORA-01438: value larger than specified precision allowed for this column

由于四舍五入而导致的第二个结果。

Thanks to everyone for the answers. It looks like the precision is the number of significant digits.

 select cast(0.000123 as number(2,5)) from dual

results in:

.00012

Where

 select cast(0.00123 as number(2,5)) from dual

and

 select cast(0.000999 as number(2,5)) from dual

both result in:

ORA-01438: value larger than specified precision allowed for this column

the 2nd one due to rounding.

雪花飘飘的天空 2024-09-01 21:58:34

根据 Oracle 文档:

小数位数可以大于精度,最常见的是使用 e 表示法时。当小数位数大于精度时,精度指定小数点右侧有效数字的最大位数。例如,定义为 NUMBER(4,5) 的列要求小数点后第一位数字为零,并将所有值舍入到小数点后第五位之后。

最好指定定点数列的小数位数和精度,以便对输入进行额外的完整性检查。指定比例和精度不会强制所有值具有固定长度。如果值超出精度,Oracle 将返回错误。如果某个值超出了范围,Oracle 将对其进行四舍五入。

According to Oracle Documentation:

Scale can be greater than precision, most commonly when e notation is used. When scale is greater than precision, the precision specifies the maximum number of significant digits to the right of the decimal point. For example, a column defined as NUMBER(4,5) requires a zero for the first digit after the decimal point and rounds all values past the fifth digit after the decimal point.

It is good practice to specify the scale and precision of a fixed-point number column for extra integrity checking on input. Specifying scale and precision does not force all values to a fixed length. If a value exceeds the precision, then Oracle returns an error. If a value exceeds the scale, then Oracle rounds it.

め可乐爱微笑 2024-09-01 21:58:34

嗯,据我了解,参考精度是位数。
最大精度为 126 位二进制数字,大致相当于 38 位十进制数字

在 oracle 中,您有 NUMBER( precision,scale) 类型,其中 precision 是总位数,scale 是小数点右侧的位数。标度可以省略,但表示为零。精度可以未指定(使用即 NUMBER(*,10)) - 这意味着总位数是根据需要的,但有 10 位正确

如果小数位数小于零,则该值将四舍五入到 scale< /code> 小数点左边的数字。
我认为如果你保留的小数点右边的数字比整个数字多,这意味着类似 0.00000000123456 但我不能 100% 确定。

Hmm as I understand the reference the precision is the count of digits.
maximum precision of 126 binary digits, which is roughly equivalent to 38 decimal digits

In oracle you have type NUMBER(precision,scale) where precision is total number of digits and scale is number of digits right of decimal point. Scale can be omitted, but it means zero. Precision can be unspecified (use i.e. NUMBER(*,10)) - this means total number of digits is as needed, but there are 10 digits right

If the scale is less than zero, the value will be rounded to scale digits left the decimal point.
I think that if you reserve more numbers right of the decimal point than there can be in the whole number, this means something like 0.00000000123456 but I am not 100% sure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文