fix(includes): 修复浮点常量精度截断与 viperlib %g 小数反转 - ConstFloat 浮点常量文本改 %.17e(全精度+LLVM合法语法, 修复 %e 6位小数截断致 llc 值错与 %.17g 裸整数报错); viperlib %g 小数位改逆序存储(原三变量交换循环在 TPV 编译产物中失效, 小数位反转 456->654); SprintfTest 增加 %g 诊断用例 T1-T10
This commit is contained in:
1 parent
61e578fe9a
commit
9ee519e998
3 files changed
+98
-44
No files matched your search
@@ -2,6 +2,7 @@ import t, c
|
||||
from stdint import *
|
||||
import string
|
||||
import viperlib
|
||||
import stdio
|
||||
import memhub
|
||||
from linkedlist import GSListNode
|
||||
from .__types import LLVMType, TypePrint
|
||||
@@ -95,10 +96,16 @@ def ConstFloat(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr,
|
||||
v.IsConst = 1
|
||||
v.FloatVal = val
|
||||
v.IntVal = 0
|
||||
# 格式化名字: LLVM IR 使用 "%e" 科学计数法(6 位小数)
|
||||
# 格式化名字: LLVM IR 浮点常量文本
|
||||
# 必须用 %.17e 保证 double 精度(17 位小数)且恒为科学计数法(带小数点),
|
||||
# LLVM 语法要求浮点常量不能是裸整数(%.17g 对 1.0 输出 "1" 会报
|
||||
# "integer constant must have integer type")。原 %e 默认仅 6 位小数,
|
||||
# 常量被截断(3.1415926535897931 -> "3.141593e+00",llc 解析后值错,
|
||||
# 导致浮点 CDefine/字面量生成错误 LLVM 值,llc 报 ret i32 0)。
|
||||
# 用 CRT stdio.snprintf: viperlib 自实现 %g 有小数位反转 bug。
|
||||
name_buf: t.CChar | t.CPtr = pool.alloc(32)
|
||||
if name_buf is not None:
|
||||
viperlib.snprintf(name_buf, 32, "%e", val)
|
||||
stdio.snprintf(name_buf, 32, "%.17e", val)
|
||||
v.Name = name_buf
|
||||
return v
|
||||
|
||||
|
||||
+22
-24
@@ -1009,19 +1009,18 @@ def vsnprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, ap: t.CChar | t.C
|
||||
if prec_e > 0:
|
||||
temp[1] = 46
|
||||
g_len = 2
|
||||
# 小数位逆序存入(个位放 g_len+prec_e-1),temp 直接为正序。
|
||||
# 原交换反转循环在 TPV 编译产物中失效(小数位未反转,如 456->654),
|
||||
# 改逆序存储,与 %f 的倒序输出一致,绕开三变量交换。
|
||||
fi: t.CInt = 0
|
||||
while fi < prec_e and g_len < TEMP_BUF_SIZE - 1:
|
||||
temp[g_len] = t.CChar(frac_p % 10 + 48)
|
||||
g_len += 1
|
||||
frac_p //= 10
|
||||
lo: t.CInt = 2
|
||||
hi: t.CInt = g_len - 1
|
||||
while lo < hi:
|
||||
tc: t.CChar = temp[lo]
|
||||
temp[lo] = temp[hi]
|
||||
temp[hi] = tc
|
||||
lo += 1
|
||||
hi -= 1
|
||||
fp_inv: t.CUInt64T = frac_p
|
||||
fp_idx: t.CInt = g_len + prec_e - 1
|
||||
while fi < prec_e and fp_idx < TEMP_BUF_SIZE - 1:
|
||||
temp[fp_idx] = t.CChar(fp_inv % 10 + 48)
|
||||
fp_idx -= 1
|
||||
fp_inv //= 10
|
||||
fi += 1
|
||||
g_len += prec_e
|
||||
else:
|
||||
prec_f: t.CInt = precision - 1 - exp10
|
||||
if prec_f < 0: prec_f = 0
|
||||
@@ -1049,19 +1048,18 @@ def vsnprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, ap: t.CChar | t.C
|
||||
frac_val *= 10.0
|
||||
p += 1
|
||||
frac_part: t.CUInt64T = t.CUInt64T(frac_val + 0.5)
|
||||
# 小数位逆序存入(个位放 g_len+prec_f-1),temp 直接为正序。
|
||||
# 原交换反转循环在 TPV 编译产物中失效(小数位未反转,如 456->654),
|
||||
# 改逆序存储,与 %f 的倒序输出一致,绕开三变量交换。
|
||||
fi = 0
|
||||
while fi < prec_f and g_len < TEMP_BUF_SIZE - 1:
|
||||
temp[g_len] = t.CChar(frac_part % 10 + 48)
|
||||
g_len += 1
|
||||
frac_part //= 10
|
||||
lo = g_len - prec_f
|
||||
hi = g_len - 1
|
||||
while lo < hi:
|
||||
tc = temp[lo]
|
||||
temp[lo] = temp[hi]
|
||||
temp[hi] = tc
|
||||
lo += 1
|
||||
hi -= 1
|
||||
fp_inv: t.CUInt64T = frac_part
|
||||
fp_idx: t.CInt = g_len + prec_f - 1
|
||||
while fi < prec_f and fp_idx < TEMP_BUF_SIZE - 1:
|
||||
temp[fp_idx] = t.CChar(fp_inv % 10 + 48)
|
||||
fp_idx -= 1
|
||||
fp_inv //= 10
|
||||
fi += 1
|
||||
g_len += prec_f
|
||||
if not alt_form and g_len > 0:
|
||||
while g_len > 0:
|
||||
if temp[g_len - 1] == 48:
|
||||
|
||||
Reference in new issue
Block a user