64位Python中的32位浮点数学运算

时间:2016-02-15 12:17:35

标签: python python-3.x floating-point precision

我编写了在32位硬件中运行32位数学运算的嵌入式软件。我经常调查浮点不精确问题。

目标调试是常规的,但为方便起见,我希望能够在我的桌面Python环境中进行快速计算,使其表现得像目标,即以32位进行数学运算。

桌面硬件,操作系统和Python安装都是64位。

我们四处谈论IEEE floats

理想情况下,在配置之后,我希望能够在Python解释器中输入0.1+0.2并让它知道使用32位数学处理和存储所有内容。

我的选择是什么?

2 个答案:

答案 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.float32ctypes.c_float,但是它们都不会让你直接将浮点文字映射到该类型,并且它们可能会使用64或80位操作,这可能导致您想要避免的舍入差异。如果你包装自己的REPL,你可以在AST级别进行文字重映射;虽然Python在codeast模块中为此提供了一些图书馆帮助,但它是一个相当复杂的主题。