我编写了在32位硬件中运行32位数学运算的嵌入式软件。我经常调查浮点不精确问题。
目标调试是常规的,但为方便起见,我希望能够在我的桌面Python环境中进行快速计算,使其表现得像目标,即以32位进行数学运算。
桌面硬件,操作系统和Python安装都是64位。
我们四处谈论IEEE floats。
理想情况下,在配置之后,我希望能够在Python解释器中输入0.1+0.2
并让它知道使用32位数学处理和存储所有内容。
我的选择是什么?
答案 0 :(得分:1)
扩展Yann Vernier的想法,这将是一个可能的转换器,它会在numpy
中注入float
导入并包装每个numpy.float32
文字。
import ast
class Float32Visitor(ast.NodeTransformer):
def visit_Module(self, node):
# add numpy import
imp = ast.Import([ast.alias("numpy")])
node.body = [imp] + node.body
return node
def visit_Num(self, node):
if not isinstance(node.n, float):
return node
return ast.Call(
func=ast.Attribute(
value=ast.Name(id="numpy", ctx=ast.Load()),
attr="float32", ctx=ast.Load()
),
args=[node],
keywords=[],
starargs=None,
kwargs=None
)
然而,将其挂钩到compile
有点棘手和苛刻。要为单个代码执行此操作,您可以执行以下操作:
import ast
parsed = ast.parse(my_code, "my_code.py", mode="exec")
parsed = Float32Visitor().visit(parsed)
code = compile(parsed, "my_code.py", mode="exec")
my_code = eval(code)
答案 1 :(得分:0)
直接的方法主要是运行为与目标匹配的环境构建的Python,即为目标构建它并在桌面硬件上的模拟器中运行它。请务必使用适当的浮点类型构建它,因为编译器将为更广泛的类型提供软件支持。效率非常低,但与模拟器一样准确。
如果你可以只使用存储行为,你可以使用numpy.float32
或ctypes.c_float
,但是它们都不会让你直接将浮点文字映射到该类型,并且它们可能会使用64或80位操作,这可能导致您想要避免的舍入差异。如果你包装自己的REPL,你可以在AST级别进行文字重映射;虽然Python在code
和ast
模块中为此提供了一些图书馆帮助,但它是一个相当复杂的主题。