124 lines
4.1 KiB
Python
124 lines
4.1 KiB
Python
from stdint import *
|
||
import t, c
|
||
import stdio
|
||
import stdlib
|
||
import testcheck
|
||
import viperlib
|
||
|
||
|
||
# ============================================================
|
||
# SprintfTest - viperlib.snprintf %a/%A 运行时验证
|
||
# 预期输出对照 glibc printf("%a", ...) 行为
|
||
# ============================================================
|
||
@t.CExport
|
||
def main() -> int:
|
||
testcheck.begin("SprintfTest: %a/%A runtime verification")
|
||
buf: bytes = stdlib.malloc(64)
|
||
|
||
# ---------- 默认精度(核心正确性) ----------
|
||
testcheck.section("default precision")
|
||
|
||
v1: t.CDouble = 1.0
|
||
viperlib.snprintf(buf, 64, "%a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x1p+0", "%a 1.0 -> 0x1p+0", "FAIL 1.0")
|
||
|
||
v2: t.CDouble = 2.0
|
||
viperlib.snprintf(buf, 64, "%a", v2)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x1p+1", "%a 2.0 -> 0x1p+1", "FAIL 2.0")
|
||
|
||
v_half: t.CDouble = 0.5
|
||
viperlib.snprintf(buf, 64, "%a", v_half)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x1p-1", "%a 0.5 -> 0x1p-1", "FAIL 0.5")
|
||
|
||
v3: t.CDouble = 3.0
|
||
viperlib.snprintf(buf, 64, "%a", v3)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x1.8p+1", "%a 3.0 -> 0x1.8p+1", "FAIL 3.0")
|
||
|
||
v_pi: t.CDouble = 3.14
|
||
viperlib.snprintf(buf, 64, "%a", v_pi)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x1.91eb851eb851fp+1", "%a 3.14 -> 0x1.91eb851eb851fp+1", "FAIL 3.14")
|
||
|
||
v0: t.CDouble = 0.0
|
||
viperlib.snprintf(buf, 64, "%a", v0)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x0p+0", "%a 0.0 -> 0x0p+0", "FAIL 0.0")
|
||
|
||
vn1: t.CDouble = -1.0
|
||
viperlib.snprintf(buf, 64, "%a", vn1)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "-0x1p+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(buf == "0X1.91EB851EB851FP+1", "%A 3.14 -> 0X1...P+1", "FAIL %A")
|
||
|
||
# ---------- # flag 强制小数点 ----------
|
||
testcheck.section("# flag")
|
||
viperlib.snprintf(buf, 64, "%#a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x1.p+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(buf == "0x1.0000000000000p+0", "%.13a 1.0 -> 0x1.0000000000000p+0", "FAIL %.13a")
|
||
|
||
# ---------- 宽度/对齐 ----------
|
||
testcheck.section("width/align")
|
||
viperlib.snprintf(buf, 64, "%10a", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == " 0x1p+0", "%10a 1.0 -> ' 0x1p+0'", "FAIL %10a")
|
||
|
||
viperlib.snprintf(buf, 64, "%-10a|", v1)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "0x1p+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(buf == "+0x1p+0", "%+a 1.0 -> +0x1p+0", "FAIL %+a")
|
||
|
||
# ---------- inf / nan ----------
|
||
testcheck.section("inf/nan")
|
||
|
||
# 构造 +inf: bit pattern 0x7FF0000000000000
|
||
inf_bits: t.CUInt64T = 0x7FF0000000000000
|
||
inf_val: t.CDouble = 0.0
|
||
c.Load(c.Addr(inf_val), c.Addr(inf_bits))
|
||
viperlib.snprintf(buf, 64, "%a", inf_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "inf", "%a +inf -> inf", "FAIL +inf")
|
||
|
||
# 构造 -inf: bit pattern 0xFFF0000000000000
|
||
ninf_bits: t.CUInt64T = 0xFFF0000000000000
|
||
ninf_val: t.CDouble = 0.0
|
||
c.Load(c.Addr(ninf_val), c.Addr(ninf_bits))
|
||
viperlib.snprintf(buf, 64, "%a", ninf_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "-inf", "%a -inf -> -inf", "FAIL -inf")
|
||
|
||
# 构造 nan: bit pattern 0x7FF8000000000000
|
||
nan_bits: t.CUInt64T = 0x7FF8000000000000
|
||
nan_val: t.CDouble = 0.0
|
||
c.Load(c.Addr(nan_val), c.Addr(nan_bits))
|
||
viperlib.snprintf(buf, 64, "%a", nan_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "nan", "%a nan -> nan", "FAIL nan")
|
||
|
||
# 大写 INF/NAN
|
||
viperlib.snprintf(buf, 64, "%A", inf_val)
|
||
testcheck.info(buf)
|
||
testcheck.check(buf == "INF", "%A +inf -> INF", "FAIL INF")
|
||
|
||
stdlib.free(buf)
|
||
return 0
|