I program embedded software that runs 32-bit math in 32-bit hardware. I routinely investigate floating point imprecision issues.
In-target debugging is routine, but for convenience I'd like to be able to do quick calculations in my desktop Python environment, having it behave like the target, i.e, do the math in 32 bits.
The desktop hardware, the OS and the Python installation are 64-bit.
We're talking IEEE floats all around.
Ideally, after configuration, I'd like to be able to type, say, 0.1+0.2
at the Python interpreter and have it already know to process and store everything using 32-bit math.
What are my options?
Python's floating-point numbers are usually 64-bit floating-point numbers, nearly equivalent to np. float64 . In some unusual situations it may be useful to use floating-point numbers with more precision.
Floating Point Numbers Floats generally come in two flavours: “single” and “double” precision. Single precision floats are 32-bits in length while “doubles” are 64-bits. Due to the finite size of floats, they cannot represent all of the real numbers - there are limitations on both their precision and range.
No, an IEEE 754 double-precision floating point number is always 64 bits. Similarly, a single-precision float is always 32 bits. If your question is about C# and/or .
How To Compare Floats in Python. If abs(a - b) is smaller than some percentage of the larger of a or b , then a is considered sufficiently close to b to be "equal" to b . This percentage is called the relative tolerance. You can specify the relative tolerance with the rel_tol keyword argument of math.
Extending Yann Vernier's idea, this would be a possible transformer that injects a numpy
import and wraps every float
literal in 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
)
Hooking this into compile
is a bit tricky and hackish, however. To do it for a single piece of code, you'd do something like this:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With