固定点运算对计算结果的影响原因分析

作者:ABAP三叔 约 5 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, Data Engineering, SD, Software Engineering, 开发, 数据工程, 软件工程, 销售分销
固定点运算对计算结果的影响原因分析 - 封面图
固定点运算对计算结果的影响原因分析 - 封面图

前言

做过定价例程增强的同学可能都被固定点运算折磨过,简单的加减乘除计算就是得不到自己想要的答案,本文将为大家介绍为什么会这样,计算的背后逻辑究竟是怎么样的。

场景模拟

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.

总结

通过几个例子可以看出来,运算中会先将小数中的小数点去掉转成整数,计算的中间结果会进行四舍五入,最后再根据小数的位数,在结果中添加小数位。

如果你在自己开发的程序中,发现计算的结果不符合预期值,可能就是固定点运算没有打上☑️,请务必保持勾选。

ABAP三叔

关于作者:ABAP三叔

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「固定点运算对计算结果的影响原因分析.md」整理生成,仅用于内部技术分享与学习交流。