前言
做过定价例程增强的同学可能都被固定点运算折磨过,简单的加减乘除计算就是得不到自己想要的答案,本文将为大家介绍为什么会这样,计算的背后逻辑究竟是怎么样的。
场景模拟
1.首先看下官方对固定点运算的介绍。
说实话,光看这个介绍,还是比较懵的,我们还是通过几个例子来简单的介绍下:
首先我们需要将固定点运算前的☑️去掉。
示例一
DATA: lv_rlt1 TYPE p DECIMALS 1, lv_rlt2 TYPE p DECIMALS 2, lv_rlt3 TYPE p DECIMALS 3.
"整除结果为5.5,取整为6,因为有1位小数,即除以10,得0.6lv_rlt1 = 11 / 2.WRITE:/ 'lv_rlt1 = ' ,lv_rlt1."整除结果为5.5,取整为6,因为有2位小数,即除以100,得0.06lv_rlt2 = 11 / 2.WRITE:/ 'lv_rlt2 = ' ,lv_rlt2."整除结果为5.5,取整为6,因为有3位小数,即除以1000,得0.006lv_rlt3 = 11 / 2.WRITE:/ 'lv_rlt3 = ' ,lv_rlt3.输出结果为,解释见代码中注释
示例二、模拟税的计算
DATA: lv_amount TYPE p DECIMALS 2 VALUE '1000.00'."不含税金额DATA: lv_amount2 TYPE p DECIMALS 2."含税金额DATA: lv_amount3 TYPE p DECIMALS 3."含税金额DATA: lv_tax_rate TYPE i VALUE 130.DATA:lv_tax TYPE p DECIMALS 2.
"130*10 = 1300,除以100得13,因为有两位小数,所以值为0.13lv_tax = lv_tax_rate * 10 / 100.WRITE:/ 'lv_tax = ' ,lv_tax."小数参与计算的时候,先去掉小数位,转为整数去计算,最后再根据小数位的位数,再进行小数位的移位
"0.13先转成了13,加上100得113,因为有2位小数,即除以100,得1.13lv_tax = lv_tax + 100.WRITE:/ 'lv_tax = ' ,lv_tax.
"1000.00先转成了100000,1.13转成了113,两者相成得11300000,除以100后得113000,因为有2位小数,即除以100,得1130.00lv_amount2 = lv_amount * lv_tax / 100.WRITE:/ 'lv_amount2 = ' ,lv_amount2.
"1000.00先转成了100000,1.13转成了113,两者相成得11300000,除以100后得113000,因为有3位小数,即除以1000,得113.000lv_amount3 = lv_amount * lv_tax / 100.WRITE:/ 'lv_amount3 = ' ,lv_amount3.
lv_amount3 = lv_amount * lv_tax * 10 / 100."小数位数多了1位,需要将原值放大10倍,最后的结果就对了WRITE:/ 'lv_amount3 = ' ,lv_amount3.输出结果为,解释见代码中注释
自定义方法计算
即使我们弄懂了其背后的原理,有时候也难免被绕晕。通常为了简便计算,会自定义计算方法,然后在定价例程中去调用。
ZFM_SD_CALCULATE 就是我编写的用来进行加减乘除计算的,代码如下:
FUNCTION zfm_sd_calculate.*"----------------------------------------------------------------------*"*"本地接口:*" IMPORTING*" REFERENCE(IV_P1) TYPE P*" REFERENCE(IV_P2) TYPE P*" REFERENCE(IV_OP) TYPE C*" EXPORTING*" REFERENCE(RV) TYPE P*"----------------------------------------------------------------------CASE iv_op. WHEN '+'. rv = iv_p1 + iv_p2. WHEN '-'. rv = iv_p1 - iv_p2. WHEN '*'. rv = iv_p1 * iv_p2. WHEN '/'. CHECK iv_p2 <> 0. rv = iv_p1 / iv_p2. ENDCASE.
ENDFUNCTION.总结
通过几个例子可以看出来,运算中会先将小数中的小数点去掉转成整数,计算的中间结果会进行四舍五入,最后再根据小数的位数,在结果中添加小数位。
如果你在自己开发的程序中,发现计算的结果不符合预期值,可能就是固定点运算没有打上☑️,请务必保持勾选。