机械规则 R2/R3/R4/R6/R7/R8/R13 + R16 保守子集,共 86 文件 2127 行。R1(T | t.CPtr)与 R12(while 下标循环)未做,仍列为待办。全量 77/77 顺序回归通过。
204 lines
7.9 KiB
Plaintext
204 lines
7.9 KiB
Plaintext
from stdint import *
|
||
import t, c
|
||
import stdio
|
||
import stdlib
|
||
import testcheck
|
||
import viperlib
|
||
import string
|
||
|
||
|
||
# ============================================================
|
||
# SprintfTest - viperlib.snprintf %a/%A 运行时验证
|
||
# 预期输出对照 glibc printf("%a", ...) 行为
|
||
# ============================================================
|
||
@t.CExport
|
||
def main() -> int:
|
||
testcheck.begin("SprintfTest: %a/%A runtime verification")
|
||
buf: bytes = stdlib.malloc(256)
|
||
|
||
# ---------- 默认精度(核心正确性) ----------
|
||
testcheck.section("default precision")
|
||
|
||
v1: double = 1.0
|
||
viperlib.snprintf(buf, 64, "%a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1p+0") == 0, "%a 1.0 -> 0x1p+0", "FAIL 1.0")
|
||
|
||
v2: double = 2.0
|
||
viperlib.snprintf(buf, 64, "%a", v2)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1p+1") == 0, "%a 2.0 -> 0x1p+1", "FAIL 2.0")
|
||
|
||
v_half: double = 0.5
|
||
viperlib.snprintf(buf, 64, "%a", v_half)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1p-1") == 0, "%a 0.5 -> 0x1p-1", "FAIL 0.5")
|
||
|
||
v3: double = 3.0
|
||
viperlib.snprintf(buf, 64, "%a", v3)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1.8p+1") == 0, "%a 3.0 -> 0x1.8p+1", "FAIL 3.0")
|
||
|
||
v_pi: double = 3.14
|
||
viperlib.snprintf(buf, 64, "%a", v_pi)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1.91eb851eb851fp+1") == 0, "%a 3.14 -> 0x1.91eb851eb851fp+1", "FAIL 3.14")
|
||
|
||
v0: double = 0.0
|
||
viperlib.snprintf(buf, 64, "%a", v0)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x0p+0") == 0, "%a 0.0 -> 0x0p+0", "FAIL 0.0")
|
||
|
||
vn1: double = -1.0
|
||
viperlib.snprintf(buf, 64, "%a", vn1)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "-0x1p+0") == 0, "%a -1.0 -> -0x1p+0", "FAIL -1.0")
|
||
|
||
# ---------- 大写 %A ----------
|
||
testcheck.section("uppercase %A")
|
||
viperlib.snprintf(buf, 64, "%A", v_pi)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0X1.91EB851EB851FP+1") == 0, "%A 3.14 -> 0X1...P+1", "FAIL %A")
|
||
|
||
# ---------- # flag 强制小数点 ----------
|
||
testcheck.section("# flag")
|
||
viperlib.snprintf(buf, 64, "%#a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1.p+0") == 0, "%#a 1.0 -> 0x1.p+0", "FAIL %#a")
|
||
|
||
# ---------- 显式精度 13(不裁剪) ----------
|
||
testcheck.section("precision 13")
|
||
viperlib.snprintf(buf, 64, "%.13a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1.0000000000000p+0") == 0, "%.13a 1.0 -> 0x1.0000000000000p+0", "FAIL %.13a")
|
||
|
||
# ---------- 宽度/对齐 ----------
|
||
testcheck.section("width/align")
|
||
viperlib.snprintf(buf, 64, "%10a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, " 0x1p+0") == 0, "%10a 1.0 -> ' 0x1p+0'", "FAIL %10a")
|
||
|
||
viperlib.snprintf(buf, 64, "%-10a|", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "0x1p+0 |") == 0, "%-10a 1.0 -> '0x1p+0 |'", "FAIL %-10a")
|
||
|
||
# ---------- show_sign ----------
|
||
testcheck.section("show_sign")
|
||
viperlib.snprintf(buf, 64, "%+a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "+0x1p+0") == 0, "%+a 1.0 -> +0x1p+0", "FAIL %+a")
|
||
|
||
# ---------- inf / nan ----------
|
||
testcheck.section("inf/nan")
|
||
|
||
# 构造 +inf: bit pattern 0x7FF0000000000000
|
||
inf_bits: uint64 = 0x7FF0000000000000
|
||
inf_val: double = 0.0
|
||
*(&inf_val) = *(&inf_bits)
|
||
viperlib.snprintf(buf, 64, "%a", inf_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "inf") == 0, "%a +inf -> inf", "FAIL +inf")
|
||
|
||
# 构造 -inf: bit pattern 0xFFF0000000000000
|
||
ninf_bits: uint64 = 0xFFF0000000000000
|
||
ninf_val: double = 0.0
|
||
*(&ninf_val) = *(&ninf_bits)
|
||
viperlib.snprintf(buf, 64, "%a", ninf_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "-inf") == 0, "%a -inf -> -inf", "FAIL -inf")
|
||
|
||
# 构造 nan: bit pattern 0x7FF8000000000000
|
||
nan_bits: uint64 = 0x7FF8000000000000
|
||
nan_val: double = 0.0
|
||
*(&nan_val) = *(&nan_bits)
|
||
viperlib.snprintf(buf, 64, "%a", nan_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "nan") == 0, "%a nan -> nan", "FAIL nan")
|
||
|
||
# 大写 INF/NAN
|
||
viperlib.snprintf(buf, 64, "%A", inf_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "INF") == 0, "%A +inf -> INF", "FAIL INF")
|
||
|
||
# ============================================================
|
||
# viperlib %g/%f/%e 浮点格式化诊断(定位 SimdTest 浮点 CDefine 值错)
|
||
# 已知现象: %a 正确, %.17g 输出 3.1397985356295141 (应为 3.1415926535897931)
|
||
# 同一 va_list 连续读同一 double, %.17g 错而 %a 对 → 定位是算法还是传参/读取
|
||
# ============================================================
|
||
testcheck.section("viperlib %g bug diagnosis")
|
||
|
||
v_pi17: double = 3.1415926535897931
|
||
v_e17: double = 2.7182818284590455
|
||
|
||
# T1: 同一参数 %.17g vs %a(复现;%a 对则说明值本身正确)
|
||
viperlib.snprintf(buf, 128, "T1 %.17g|%a", v_pi17, v_pi17)
|
||
testcheck.info(buf)
|
||
|
||
# T2: 两个 %.17g 不同值
|
||
viperlib.snprintf(buf, 128, "T2 %.17g|%.17g", v_pi17, v_e17)
|
||
testcheck.info(buf)
|
||
|
||
# T3: CRT 对照
|
||
stdio.snprintf(buf, 128, "T3 %.17g|%a", v_pi17, v_pi17)
|
||
testcheck.info(buf)
|
||
|
||
# T4: 不同精度
|
||
viperlib.snprintf(buf, 128, "T4 %.17g|%.10g|%.6g|%g", v_pi17, v_pi17, v_pi17, v_pi17)
|
||
testcheck.info(buf)
|
||
|
||
# T5: %f / %e
|
||
viperlib.snprintf(buf, 128, "T5 %.17f|%.17e", v_pi17, v_pi17)
|
||
testcheck.info(buf)
|
||
|
||
# T6: 简单精确值(1.0/0.5 二进制精确, 若这些也错则算术层坏)
|
||
viperlib.snprintf(buf, 128, "T6 %.17g|%.17g|%.17g", 1.0, 0.5, 123.456)
|
||
testcheck.info(buf)
|
||
|
||
# T7/T8: double 在变参不同位置(va_list 读取位置相关性)
|
||
viperlib.snprintf(buf, 128, "T7 %d|%.17g|%d", 100, v_pi17, 200)
|
||
testcheck.info(buf)
|
||
viperlib.snprintf(buf, 128, "T8 %d|%d|%.17g", 100, 200, v_pi17)
|
||
testcheck.info(buf)
|
||
|
||
# T9: 字面量直接传(非常量折叠则看传递路径)
|
||
viperlib.snprintf(buf, 128, "T9 %.17g|%a", 3.1415926535897931, 3.1415926535897931)
|
||
testcheck.info(buf)
|
||
|
||
# T10: 顺序反转, %a 在前 %.17g 在后
|
||
viperlib.snprintf(buf, 128, "T10 %a|%.17g", v_pi17, v_pi17)
|
||
testcheck.info(buf)
|
||
|
||
# ============================================================
|
||
# 多整数变参复现(DefineTest test_define_string PAGE= 遗留 bug):
|
||
# viperlib.snprintf 3+ 个 int 变参时, 第 2 个 %d 读到垃圾
|
||
# (va_arg 游标从寄存器区切到溢出区推进错误, 非本次 CIf 引入)
|
||
# 预期: R1-R3 目前 FAIL, 修复后应全部 PASS
|
||
# ============================================================
|
||
testcheck.section("multi-int varargs repro")
|
||
|
||
# R1: 3 个常量 int(复现 DefineTest "MAX_SIZE=%d PAGE=%d MASK=0x%x" 模式)
|
||
viperlib.snprintf(buf, 128, "R1 %d|%d|%d", 1024, 4096, 255)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "R1 1024|4096|255") == 0, "R1 3-const-int (1024|4096|255)", "R1 FAIL (第2变参被误读)")
|
||
|
||
# R2: 3 个运行时变量 int(排除常量折叠差异)
|
||
ia: int = 1024
|
||
ib: int = 4096
|
||
ic: int = 255
|
||
viperlib.snprintf(buf, 128, "R2 %d|%d|%d", ia, ib, ic)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "R2 1024|4096|255") == 0, "R2 3-var-int (1024|4096|255)", "R2 FAIL (第2变参被误读)")
|
||
|
||
# R3: 4 个变参(游标推进进一步暴露)
|
||
viperlib.snprintf(buf, 128, "R3 %d|%d|%d|%d", 1, 2, 3, 4)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "R3 1|2|3|4") == 0, "R3 4-int (1|2|3|4)", "R3 FAIL (变参游标推进错误)")
|
||
|
||
# R4: 第 2 个变参为 0(值 0 若被截断读也会暴露)
|
||
viperlib.snprintf(buf, 128, "R4 %d|%d|%d", 100, 0, 200)
|
||
testcheck.info(buf)
|
||
testcheck.check(string.strcmp(buf, "R4 100|0|200") == 0, "R4 middle-zero (100|0|200)", "R4 FAIL (第2变参被误读)")
|
||
|
||
stdlib.free(buf)
|
||
return 0
|