forked from erp-dev/erp
119 lines
5.3 KiB
Markdown
119 lines
5.3 KiB
Markdown
# 好布业 ERP 金额计算规则报告
|
||
|
||
**—— 计价引擎舍入规则逆向分析 ——**
|
||
|
||
编制日期:2026 年 6 月
|
||
|
||
---
|
||
|
||
## 一、结论摘要
|
||
|
||
经过逐步测试与逻辑反推,好布业 ERP 系统的金额计算规则已被完整还原。核心规则可用一行公式表达:
|
||
|
||
> **总价 = ROUND ( 数量 × 单价 , 0 ) —— 逢五进一(round-half-up)**
|
||
|
||
**关键特征:** 输入阶段不舍入,按原始小数相乘;只在生成总价时把乘积四舍五入到整数(元),逢 0.5 进位。
|
||
|
||
---
|
||
|
||
## 二、分析背景
|
||
|
||
在日常使用中发现,系统的总价金额始终为整数,单价或数量中携带的小数似乎在某一环节被处理掉了。为弄清系统究竟在哪一步、按什么规则处理小数,本次分析采用受控输入测试法:固定其他变量,逐组输入特定数值,观察输出总价,从而逆向推断计算引擎的真实行为。
|
||
|
||
需要回答三个核心问题:
|
||
|
||
- 舍入规则是什么——四舍五入、截断(向下取整)还是其他?
|
||
- 舍入发生在哪一步——输入阶段(先舍单价/数量)还是乘积阶段(先乘后舍)?
|
||
- 逢五如何处理——逢五进一还是银行家舍入(逢五取偶)?
|
||
|
||
---
|
||
|
||
## 三、测试数据与观察
|
||
|
||
以下为全部实测数据,按测试目的分组列出。
|
||
|
||
### 3.1 基础舍入测试
|
||
|
||
| 数量 | 单价 | 理论乘积 | 实际总价 | 说明 |
|
||
|:---:|:---:|:---:|:---:|:---:|
|
||
| 1 | 1.4 | 1.4 | **1** | 舍去 |
|
||
| 1 | 1.49 | 1.49 | **1** | 舍去 |
|
||
| 1 | 1.5 | 1.5 | **2** | 进位 |
|
||
|
||
**观察:** 1.5 → 2 进位,说明并非截断(若为截断/向下取整,1.5 应得 1)。结合 1.49 → 1,规则锁定为四舍五入。
|
||
|
||
### 3.2 对称性测试(小数放数量 vs 放单价)
|
||
|
||
| 数量 | 单价 | 实际总价 | 说明 |
|
||
|:---:|:---:|:---:|:---:|
|
||
| 1.49 | 1 | **1** | 小数在数量 |
|
||
| 1 | 1.49 | **1** | 小数在单价 |
|
||
| 1.5 | 1 | **2** | 小数在数量 |
|
||
| 1 | 1.5 | **2** | 小数在单价 |
|
||
|
||
**观察:** 无论小数落在数量还是单价,处理结果一致,舍入对称。但这些组合均有一个因子为 1,乘积等于小数本身,无法区分“先舍输入”与“先乘后舍”。
|
||
|
||
### 3.3 关键测试:舍入发生在哪一步
|
||
|
||
使两个因子都不为整数且不为 1,让两种引擎给出不同结果:
|
||
|
||
| 数量 | 单价 | 先舍输入预期 | 先乘后舍预期 | 实际总价 |
|
||
|:---:|:---:|:---:|:---:|:---:|
|
||
| 1.5 | 1.5 | 2×2 = 4 | round(2.25) = 2 | **2** |
|
||
|
||
**结论:** 实际为 2,等于 round(1.5 × 1.5) = round(2.25)。证明系统先按原始小数相乘、再对乘积舍入,输入阶段不舍入。同时否定了“单价/数量在进入计算前即被取整”及“字段为 INT”的早期猜测——内部计算至少保留小数(很可能为 decimal)。
|
||
|
||
### 3.4 收尾测试:逢五进一 vs 银行家舍入
|
||
|
||
此前的进位样本(1.5→2、2.25→2)恰好两种规则结果相同,无法区分。选取乘积正好为 2.5 的点(2 为偶数,银行家舍入会归 2)进行判定:
|
||
|
||
| 数量 | 单价 | 逢五进一预期 | 银行家舍入预期 | 实际总价 |
|
||
|:---:|:---:|:---:|:---:|:---:|
|
||
| 1 | 2.5 | 3 | 2 | **3** |
|
||
|
||
**结论:** 实际为 3,确认为逢五进一(round-half-up),排除银行家舍入。
|
||
|
||
---
|
||
|
||
## 四、最终规则与计算流程
|
||
|
||
综合全部测试,系统计价流程如下:
|
||
|
||
| 环节 | 行为 |
|
||
|:---|:---|
|
||
| **输入(数量、单价)** | 保留原始小数,不做任何舍入 |
|
||
| **乘法** | 用原始小数相乘,得到带小数的乘积 |
|
||
| **生成总价** | 对乘积四舍五入到整数;乘积小数部分 ≥ 0.5 进位(逢五进一,非银行家舍入) |
|
||
| **存储 / 显示** | 以整数(元)为单位呈现 |
|
||
|
||
**计算流程示意:**
|
||
|
||
```
|
||
输入(原始小数) → 数量 × 单价(保留小数) → ROUND 到整数(逢五进一) → 整数元存储/显示
|
||
```
|
||
|
||
---
|
||
|
||
## 五、系统性质判定
|
||
|
||
- **精度等级:** 对外结算精度为 0 位小数(整数元),但内部计算保留小数参与运算。
|
||
- **舍入位置:** 位于乘积阶段(先乘后舍),而非输入阶段。
|
||
- **舍入方式:** 四舍五入、逢五进一(round-half-up)。
|
||
- **数据本质:** 金额字段对外表现为整数,但计算层非 INT 截断,更接近 decimal 计算后取整。
|
||
- **适用定性:** 属于“元级整数结算”的简化型计价系统,不处理角、分、厘等小单位。
|
||
|
||
---
|
||
|
||
## 六、使用建议与注意事项
|
||
|
||
- 单条记录的小数部分会被舍入,多条汇总时可能产生“先汇总再取整”与“逐条取整再相加”的差异,对账时需明确以哪种口径为准。
|
||
- 由于逢五进一,金额在临界值(乘积恰为 X.5)会整体偏高,长期累积对总额有轻微上偏影响,财务核算时可留意。
|
||
- 若需更高精度(保留角/分),需在系统层调整结算精度,单纯依赖现有规则无法还原小数金额。
|
||
- 建议在正式启用前,对“数量与单价均带两位以上小数”的组合再抽样复核,确保乘积舍入行为在更复杂数值下依旧一致。
|
||
|
||
---
|
||
|
||
## 附录:规则一句话总结
|
||
|
||
> 该 ERP 系统在金额计算中,按原始小数完成「数量 × 单价」后,对乘积统一四舍五入(逢五进一)为整数元,输入阶段不舍入,最终结算单位为元级整数金额。
|