python hack converting floats to decimals - python-3.x

I've written a large program, with dependencies on libraries written in my lab. I'm getting wrong (and somewhat random) results, which are caused by floating-point errors.
I would like to do some python magic and change all floats to decimals, or some other more precise type.
I can't write the full code here, but following is the general flow -
def run(n):
...
x = 0.5 # initializes as float
for _ in range(n):
x = calc(x)
...
return x
What I'm trying to avoid is to go over all initialization in the code and add a manual cast to decimal.
Is there a trick I can do to make python initialize all floats in lines such as x = 0.5 as decimals? or perhaps use a custom interpreter which has more exact floats?
Thanks,
I can't post the full code, hope my edit makes it clearer.

I think you can use this:
from decimal import Decimal
Decimal(variable)

Related

Square root of a positive fraction gives complex number in Python

Consider this example-
(-25.0000001**2)**(1/2)
This returns-
Python 3.8.3
(1.5308085050574255e-15+25.0000001j)
Now I expected some tiny errors. But this looks like a complex number. What does this mean?
Does python simply use the complex representation to describe numbers with very tiny decimals?
Also, I know that this is hugely inefficient but just to test the limits.
That is just a side-effect of Python Operator Precedence, you'll realize that
>>> -25**2
-625
>>> (-25)**2
625
Since the exponentian (**) is given precedence over negative(-) the result comes out to be -625. which square rooted gives you that complex number.
You should be doing this instead:
>>> ((-25.0000001)**2)**(1/2)
25.0000001

More elegant method to take user-input vector as a float64?

I'm reprogramming an orbital analysis program that I wrote in MATlab in Python 3.7. The initial inputs of velocity and position are queried user inputs. The method I'm using currently is clunky feeling (I am a python beginner) and I'm wondering if someone can suggest a more elegant method to take this input vector as a numpy float64? I suspect this problem is trivial but I haven't found a clear answer yet...
The current input is a vector with the syntax: "i,k,j". no spaces, comma delimited. Each component is converted to a float64 in a list via list(map(float, input)), I then have to convert it back to numpy float64 in order to use r as a vector later on.
v = np.float64(list(map(np.float64,input('Query Text').split(','))))
I'd say that's pretty elegant already. I'd do it like this if you like it better:
np.float64(
[np.float64(i) for i in input("Query text").split(",")]
)
but i wouldn't say this is much more elegant, but at least it does the same thing.

What changed between python 2.7 and 3.x to affect this "snap to grid" code?

For a long time now I've used this little "algorithim" to snap things to a grid in python 2.7:
mouse_x,mouse_y=31,45
mse=[mouse_x,mouse_y]
mse_snap=(((mse[0])/32)*32,((mse[1])/32)*32)
print(mse_snap)
and it would output: [0,32]
essentially snapping it to the closest position on a 32x32 grid (or whatever size I wanted).
BUT! Now, I've upgraded to Python 3.6 and the exact same code outputs: [31.0,45.0]
I don't really know whats going on here, or where to begin researching to find out. Can anyone offer some intel.
Python 2 integer division also floors the result, while Python 3 will return a floating point number.
Python 2.7:
>>> 31/32
0
Python 3.5:
>>> 31/32
0.96875
You can make it behave as expected by replacing the last line with
mse_snap=(int((mse[0])/32)*32, int((mse[1])/32)*32)
Edit: This is identical as long as the values are positive. Converting to an int rounds towards zero, which is identical to floor only with positive numbers. If you expect negative values, use math.floor instead:
from math import floor
...
mse_snap=(floor((mse[0])/32)*32, floor((mse[1])/32)*32)

python division result not true and different results

I am trying to solve fractional knapsack problem.
I have to find items with maximum calories per weight. I will fill my bag up to defined/limited weight with maximum calories.
Though algorithm is true, I can't find true result because of python division weirdness
When I try to find items with max calories per weight (python3)
print ((calories_list[i]/weight_list[i])*10)
# calories[i] 500 and weight[i] 30 (they're integers)
166.66666666666669
on the other hand, I opened terminal and typed python3
>>> 500/30
16.666666666666668
#when multiply with 10, it must be 16.666666666666668 not
#166.66666666666669
as you see, it gives different results
most of all, the important thing is that the real answer
500/30=16.6666666667
I got stucked here two days ago, please help me
Thanks you
As explained in the Python FAQ:
The float type in CPython uses a C double for storage. A float object’s value is stored in binary floating-point with a fixed precision (typically 53 bits) and Python uses C operations, which in turn rely on the hardware implementation in the processor, to perform floating-point operations. This means that as far as floating-point operations are concerned, Python behaves like many popular languages including C and Java.
You could use the decimal module as an alternative:
>>> from decimal import Decimal
>>> Decimal(500)/Decimal(30)
Decimal('16.66666666666666666666666667')

How can I keep python from truncating large numbers after division

I am trying to do division with very large numbers. I know that python can handle them before the division, but is there a way to keep python from truncating the answer?
an example follows:
s =
68729682406644277238837486231747530924247154108646671752192618583088487405790957964732883069102561043436779663935595172042357306594916344606074564712868078287608055203024658359439017580883910978666185875717415541084494926500475167381168505927378181899753839260609452265365274850901879881203714
M =
2047
s/(2*M) = 1.6787904837968803e+289
It can remember the 292 digit number s but when it divides the large number it gets truncated.
Is there any way that I can get an exact answer?
Thanks
If you are only concerned with the integer part of the answer, you can use // which is the integer division operator:
s // (2*M)
It looks like your s is a multiple of M so it sounds like this is what you are looking for.
In Python (3 and later), the / operator is the floating point division operator, while // is the integer division operator. Previous versions of Python had only / and would do different things depending on whether the operands were both integers or not. This was confusing, so a new // operator was introduced and / was redefined to be always floating point.

Resources