Maximizing Multiplier Based on Precision in Python
Question:
Given the following equation:
x / y = z
Where the precision of x
is 5 and the precision of z
is 8, given the following values of x
, y
:
from decimal import Decimal
x = Decimal('15.00000')
y = Decimal('81.63')
x_prec = 5
z_prec = 8
z_unrounded = x / y # 0.1837559720690922454979786843...
z = round(z_unrounded, z_prec) # 0.18375597
the value of 0.18375597
for z
is produced, which when multiplied by y
gives a value of 14.9999998311
.
Given the precision of x, we can "max" the value of z
to 0.18375603
, since:
z_max = Decimal('0.18375603')
x_unrounded = y * z_max # 15.0000047289
x = round(x_unrounded, x_prec) # 15.00000
I know that I can find this z_max
value in a loop:
extra_z = Decimal('0.0')
min_z = Decimal('0.00000001')
while True:
next_z = z + extra_z + min_z
if round(y * next_z, x_prec) > x:
break
extra_z += min_z
extra_z # 0.00000006
max_z = z + extra_z # 0.18375603
But using this sort of method feels wrong, or at least that I’m missing some key insight about precision and Decimal
values.
Is there a clearer or more algebraic way of calculating max_z
?
Answers:
You are talking about significant figures. Wiki has a lot of info on it.
If x=1.0 and y=1.0, which have both 2 significant numbers, and you want to find the maximum allowable range for z, then checking the limits for the number x will suffice. In this case the range is from 0.95 to 1.049999. These two values are the limits if x_prec = 2 and will both round to 1.0.
Generally speaking, the precision of a product (or quotient) of two numbers is the minimum precision of the two factors (or of dividend and divisor).
- To a first approximation (pun intended), check out what Wikipedia says about significant figures.
- For a fully general answer, look into the mathematical field of error analysis.
In your particular case, the precision of x
is 5
, so any product/division involving x
can’t have higher precision than that. The number 0.18375
does seem to have a precision of 5
.
Being a calculated quantity, the precision of z
of course depends on that of y
as well; it would be min(x_prec, y_prec)
, even if z
nominally has a precision of 8
.
I agree with the other answerer that, once you know the allowable range for each of x
and y
, you can just calculate the corresponding range for z
as zMin = xMin/yMax
and zMax = xMax/yMin
(easy in this case). For a fully general answer, error analysis is your friend.
Given the following equation:
x / y = z
Where the precision of x
is 5 and the precision of z
is 8, given the following values of x
, y
:
from decimal import Decimal
x = Decimal('15.00000')
y = Decimal('81.63')
x_prec = 5
z_prec = 8
z_unrounded = x / y # 0.1837559720690922454979786843...
z = round(z_unrounded, z_prec) # 0.18375597
the value of 0.18375597
for z
is produced, which when multiplied by y
gives a value of 14.9999998311
.
Given the precision of x, we can "max" the value of z
to 0.18375603
, since:
z_max = Decimal('0.18375603')
x_unrounded = y * z_max # 15.0000047289
x = round(x_unrounded, x_prec) # 15.00000
I know that I can find this z_max
value in a loop:
extra_z = Decimal('0.0')
min_z = Decimal('0.00000001')
while True:
next_z = z + extra_z + min_z
if round(y * next_z, x_prec) > x:
break
extra_z += min_z
extra_z # 0.00000006
max_z = z + extra_z # 0.18375603
But using this sort of method feels wrong, or at least that I’m missing some key insight about precision and Decimal
values.
Is there a clearer or more algebraic way of calculating max_z
?
You are talking about significant figures. Wiki has a lot of info on it.
If x=1.0 and y=1.0, which have both 2 significant numbers, and you want to find the maximum allowable range for z, then checking the limits for the number x will suffice. In this case the range is from 0.95 to 1.049999. These two values are the limits if x_prec = 2 and will both round to 1.0.
Generally speaking, the precision of a product (or quotient) of two numbers is the minimum precision of the two factors (or of dividend and divisor).
- To a first approximation (pun intended), check out what Wikipedia says about significant figures.
- For a fully general answer, look into the mathematical field of error analysis.
In your particular case, the precision of x
is 5
, so any product/division involving x
can’t have higher precision than that. The number 0.18375
does seem to have a precision of 5
.
Being a calculated quantity, the precision of z
of course depends on that of y
as well; it would be min(x_prec, y_prec)
, even if z
nominally has a precision of 8
.
I agree with the other answerer that, once you know the allowable range for each of x
and y
, you can just calculate the corresponding range for z
as zMin = xMin/yMax
and zMax = xMax/yMin
(easy in this case). For a fully general answer, error analysis is your friend.