`

Oracle特殊情况下数字四舍五入问题

阅读更多


奇怪的数据,select出来明明是0.0140625,但通过round(vv,6)出来的却没有四舍五入。按理应该得到:0.014063,实际却得到:0.014062。违背了四舍五入的原则。

案例:

drop table tt ;
create table tt as
select a, v, exp(sum(ln(1 + v)) over(order by rownum)) - 1 x
  from (select a, lag(a, 1, a) over(order by r desc) / a - 1 v
          from (select 1.2980 a, 2 r
                  from dual
                union all
                select 1.2800 a, 1 r from dual))

SQL> select a, v, round(v,6) round_v, x, round(x,6) round_x from tt a;

         A          V    ROUND_V         x   ROUND_x
---------- ---------- ---------- ---------- ----------
     1.298          0          0          0          0
      1.28  0.0140625   0.014063  0.0140625   0.014062

仔细观察以上结果,可发现字段v和字段x是“相同”的,都是0.0140625,。但是对这两个字段同样的round 6却出现了不同的结果。v对应的round_v是0.014063,即四舍五入了。而x对应的round_x是0.014062,没有四舍五入。

进一步dump后发现,其实内部的数据存储是不一样的:
v的dump结果:
Typ=2 Len=5: 192,2,41,63,51
x的dump结果:
Typ=2 Len=20: 192,2,41,63,50,100,100,100,100,100,100,100,100,100,100,100,100,100
同样的数据,存储的差异却很大。

现在,再来深入挖掘一下,对x的dump结果进行翻译:
有192得到指数位:192-193=-1
然后再得到各个数字位:
(2 - 1) * 100^ (-1 - 0)     +
(41 - 1) * 100^( -1 - 1)   +
(63 - 1) * 100^( -1 - 2)   +
(50 - 1) * 100^( -1 - 3)   +
(100 - 1) * 100^( -1 - 4)
=0.0140624999

现在,知道为什么了。
因为Oracle内部的存储是0.0140624999,也就是说,小数点后第七位是4,而不是5,因此四舍五入的时候没有“入”。v的翻译结果就是0.0140625,因此“入”了。
不知道这是显示的问题还是Oracle处理的一个bug,出现这个问题的因素有两个:
1、exp ln函数的使用。如果直接使用加减乘除是可以得到正确的结果的。
2、只有x.xxxxx49999这种情况才会导致数据差异。由此导致的问题还是比较明显的。
  • 大小: 47.2 KB
分享到:
评论

相关推荐

    自己写的Oracle四舍六入奇进偶不进的函数

    - 其他情况下,则直接进行四舍五入处理。 - 最后,根据输入数值的正负,将其转换为字符串格式并返回。 #### 测试与应用 为了确保函数的正确性,开发者已经进行了充分的测试,并将此函数成功应用于实际项目中。这...

    oracle中将小写金额转换为大写金额函数

    首先,函数会计算输入金额的绝对值,并将其四舍五入到分位,然后转换为字符串形式。 ```sql l_money := ABS(money); IF money l_sign := '负'; ELSE l_sign := ''; END IF; tmp := ROUND(l_money, 2) * 100; c_...

    oracle内部讲义3-6.pptx

    数字函数可以对数字进行四舍五入、截断、求余等操作。 字符函数 字符函数可以控制字符的大小写、截断、concatenate 等操作。常见的字符函数包括: * LOWER: 将字符转换为小写 * UPPER: 将字符转换为大写 * ...

    java_oracle_day02.pdf

    该函数有两个参数:第一个是要进行四舍五入的数字,第二个是四舍五入到小数点后几位。如果第二个参数省略,默认为0,即四舍五入到整数。例如,在案例1中,通过计算员工的薪资与一个固定比率的乘积,并使用`round()`...

    ORACLE的基本函数

    `round()`函数在ORACLE中用于四舍五入一个数值到指定的小数位数。如果未指定小数位数,则默认四舍五入至最接近的整数。 ##### 案例: - **计算金额的四舍五入**:例如,若要计算员工薪资乘以0.1234567后的金额,并...

    oracle教学4笔记

    - `TRUNC`:截取,不会进行四舍五入 - `MOD`:取余数 4. **转换函数:** - `TO_DATE`:将字符型数据转换为日期类型 - `TO_CHAR`:将数字或日期类型转换为字符类型 - `TO_NUMBER`:将字符转换为数值类型 5. **...

    oracle求整

    在Oracle数据库中,对于数字的取整处理通常涉及到去除小数部分或者对数字进行四舍五入等操作。这些操作可以使用内置的函数如`TRUNC`、`ROUND`等来完成。其中`TRUNC`函数被广泛用于去除数字的小数部分,从而达到取整...

    oracle 内置函数大全

    - `ROUND(x[,d])`:四舍五入到指定的小数位数d。 - `TRUNC(x[,d])`:截断到指定的小数位数d,不进行四舍五入。 - `MOD(x,y)`:返回x除以y的余数。 2. **字符串函数**: - `CONCAT(str1, str2, ..., strn)`:...

    关于oracle自带的表

    - **`round(23.652, 2)`**: 四舍五入到小数点后两位(结果为 23.65)。 - **`round(23.652, -1)`**: 四舍五入到小数点前一位(结果为 20)。 3. **日期处理函数** - **`to_char(sal, '$99,999.9999')`**: 将数字...

    oracle函数大全.rar

    1. **数学函数**:如ROUND、TRUNC、MOD等,用于对数字进行四舍五入、截断或取模运算。 2. **日期和时间函数**:如SYSDATE、ADD_MONTHS、EXTRACT等,帮助处理日期和时间数据,进行日期计算或提取日期部分。 3. **字符...

    oracle函数大全(分类显示).zip

    - `ROUND`:对数字进行四舍五入。 - `TRUNC`:截断数字到指定的小数位数。 - `MOD`:返回两个数相除的余数。 - `SQRT`:计算平方根。 - `POWER`:计算一个数的幂次。 2. **字符串函数**: - `LENGTH`:返回...

    oracle数据库面试题

    Oracle还提供了多种数字函数,如`ABS()`(绝对值)、`EXP()`(指数函数)、`CEIL()`和`FLOOR()`(向上和向下取整)、`TRUNC()`和`ROUND()`(截断和四舍五入)、`SIGN()`(符号函数)和`MOD()`(取模运算)。...

    Oracle学习笔记_(PDF版)

    - **四舍五入**: `ROUND(字段, 保留位数)` 进行四舍五入 - **格式转换**: - 将数字转换为特定格式的字符串:`TO_CHAR(字段, '格式')` - 转换为本地货币格式:`TO_CHAR(字段, 'L格式')` - 转换日期格式(24小时制...

    oracle常用函数使用说明

    - `ROUND(number[, digits])`:四舍五入到指定的小数位数。 5. **转换函数**:在不同数据类型之间转换: - `TO_CHAR(date_or_number[, format_mask])`:将日期或数字转换为字符串。 - `TO_DATE(string[, format_...

    Oracle 实用教程(全面实用)

    - **单记录数字函数**:例如`ROUND()`用于四舍五入,`TRUNC()`用于截断数字。 - **单记录日期函数**:例如`SYSDATE`用于返回当前系统日期,`ADD_MONTHS()`用于增加月份。 - **单记录转换函数**:例如`TO_CHAR()`...

    Oracle 函数大全

    例如,`ABS()`返回一个数的绝对值,`SQRT()`计算平方根,`ROUND()`和`TRUNC()`分别用于四舍五入和截断数字到指定的小数位数。还有`MOD()`函数用于计算两数相除的余数。 **日期函数**在处理时间序列数据时必不可少。...

    oracle模拟试卷解读.docx

    ROUND函数用于四舍五入,第一个参数是数值,第二个参数是小数位数,-1表示对整数部分进行操作,所以45.953四舍五入到个位是46。TRUNC函数则用于截断数字,第二个参数同样是小数位数,2表示保留两位小数,因此45.936...

    oracle 内置sql函数

    数字函数主要处理数值运算,如`ROUND`用于四舍五入,`TRUNC`用于截断小数部分,`MOD`计算余数等。 **F.4 日期函数** 日期函数处理日期和时间数据,如`SYSDATE`获取当前系统日期,`ADD_MONTHS`增加或减少月份,`...

    Oracle的110个自带函数总结归纳

    - ROUND():四舍五入到指定的小数位数。 - MOD():求余数。 - POWER():计算一个数的幂。 2. 字符串函数: - CONCAT():连接两个或更多字符串。 - SUBSTR():从字符串中提取子串。 - LENGTH():返回字符串...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    ORACLE用户是学习ORACLE数据库中的基础知识,下面就介绍下类系统常用的默认ORACLE用户: 1. sys用户:超级用户,完全是个SYSDBA(管理数据库的人)。拥有dba,sysdba,sysoper等角色或权限。是oracle权限最高的用户,...

Global site tag (gtag.js) - Google Analytics