算术表达式 (★★)
#arithmetic #data-types
数值类型比较
| 类型 |
关键字 |
精度 |
范围 |
特殊行为 |
| 整数 |
i |
4 字节,整数 |
-2^31 到 2^31-1 |
商业舍入用于除法 |
| 二进制浮点 |
f |
8 字节,IEEE 754 |
~1E-307 到 ~1E+308 |
舍入误差;17位显示 |
| 压缩数 |
p |
1-16 字节,1-31 位 |
最多 31 位 |
需要 DECIMALS;需要定点算术属性 |
| 十进制浮点 16 |
decfloat16 |
8 字节 |
16位精度 |
笔纸算法;无舍入误差 |
| 十进制浮点 34 |
decfloat34 |
16 字节 |
34位精度 |
笔纸算法;无舍入误差 |
整数算术
- 商业舍入:除法舍入到最接近的整数(不是截断)
DIV 运算符:整数除法返回商
MOD 运算符:整数取模返回余数
1 2 3 4 5 6 7 8
| DATA: lv_int TYPE i.
lv_int = 5 / 2. " 结果:3(商业舍入) lv_int = -5 / 2. " 结果:-2(向绝对值更大的方向舍入)
" DIV 和 MOD lv_result = 7 DIV 2. " = 3 lv_result = 7 MOD 2. " = 1
|
二进制浮点数(类型 f)
- 基于 IEEE 754 标准(双精度)
- 内部以二进制尾数 + 指数存储
- 无法精确表示所有十进制小数
- 显示使用 17 位有效数字(足以重建二进制值)
- 比较可能因舍入而失败:
0.1 + 0.2 <> 0.3 可能为真
1 2 3 4
| DATA: lv_float TYPE f.
lv_float = '0.1'. " 必须使用文本字面量进行精确的十进制输入 lv_float = 0.1. " 转换时可能已有舍入误差
|
压缩数(类型 p)
- 定点算术:小数点随值一起存储
- 使用
LENGTH(字节)和 DECIMALS(小数位)定义
- 总位数 = 2 * LENGTH - 1
- **程序属性”定点算术”**必须激活
- 如果未设置:计算中忽略小数位;仅用于 I/O 格式化
1 2 3 4 5
| DATA: lv_packed TYPE p LENGTH 8 DECIMALS 2.
" 不带定点算术属性: " 1.50 + 1.50 = 3.00 (存储/打印正确) " 1.50 * 2 = 300 (错误!计算中未考虑小数位)
|
十进制浮点数(decfloat16 / decfloat34)
- 使用笔纸算法(基于十进制,非二进制)
- 十进制小数无舍入误差
decfloat16:16 位有效数字,8 字节
decfloat34:34 位有效数字,16 字节
- 财务和精度关键计算的最佳选择
混合算术类型确定
当不同数值类型出现在同一表达式中时,结果类型遵循优先级层次:
1 2 3 4 5
| 优先级(从高到低): decfloat16 / decfloat34 --> 十进制浮点算术 f --> 二进制浮点算术 p --> 压缩(定点)算术 i --> 整数算术
|
| 条件 |
使用的算术 |
任何 decfloat16/decfloat34 操作数或结果 |
十进制浮点 |
任何 f 操作数或结果(无 decfloat) |
二进制浮点 |
任何 p 操作数或结果(无 f,无 decfloat) |
定点(压缩) |
所有 i 操作数和结果 |
整数 |
1 2 3 4 5
| " 示例:** 改变一切 DATA: lv_int TYPE i.
lv_int = ( 1 / 4 ) * ( 2 * 2 ). " 整数算术:(0) * 4 = 0 lv_int = ( 1 / 4 ) * ( 2 ** 2 ). " 浮点算术:0.25 * 4.0 = 1
|
1 2 3 4 5
| " 大字面量将算术改为压缩数 DATA: lv_int TYPE i.
lv_int = 1000000000 / 300000000 * 3. " 整数:结果 = 9 lv_int = 10000000000 / 3000000000 * 3. " 压缩数:结果 = 10
|
算术运算符汇总
| 运算符 |
含义 |
说明 |
+ - |
加、减 |
标准 |
* / |
乘、除 |
类型相关 |
DIV |
整数商 |
仅整数类型 |
MOD |
整数余数 |
仅整数类型 |
** |
幂 |
始终触发浮点算术 |
**= |
幂并赋值 |
内联版本 |
选择正确的数值类型
1 2 3 4 5 6 7 8 9 10
| +------------------+------------------------------------------+ | 使用场景 | 推荐类型 | +------------------+------------------------------------------+ | 计数、索引 | i (最快,原生) | | 财务计算 | p 或 decfloat34 (精确小数) | | 科学计算 | f (大范围,IEEE 754) | | 最高精度 | decfloat34 (34位,无舍入) | | 高精度 | decfloat16 (16位,更少内存) | | 遗留代码 | p (传统 ABAP) | +------------------+------------------------------------------+
|
考试/测试模式
| 关键词/模式 |
答案 |
| “商业舍入” |
整数除法舍入到最接近的整数 |
| “类型 f 舍入误差” |
IEEE 754 二进制无法精确表示所有十进制小数 |
| “17 位” |
类型 f 的显示精度 |
| “定点算术” |
程序属性;必须为类型 p 的小数位设置 |
| “笔纸算法” |
decfloat 算法;无舍入误差 |
“** 运算符” |
无论操作数类型如何,都强制浮点算术 |
| “字面量超出 i 范围” |
自动变为 p 类型;改变表达式算术 |
| “decfloat vs f” |
decfloat = 精确十进制;f = 带舍入误差的二进制 |
| “DIV / MOD” |
整数商和余数运算符 |
| “混合表达式类型” |
由表达式中最高优先级的类型决定 |
相关笔记