a = 15511210043330985984000000 # (25!)
b = 479001600 # (12!)
c = 6227020800 # (13!)
On dividing ans = int(a/(b*c)) or ans = int((a/b)/c) we get ans equal to 5200299 instead of 5200300
In Python 3.x / means floating point division and can give small rounding errors. Use // for integer division.
ans = a // (b*c)
Try using integer division instead of float division.
>>> 15511210043330985984000000 / (479001600 * 6227020800)
5200299.999999999
>>> 15511210043330985984000000 // (479001600 * 6227020800)
5200300
Your problem (not using integer arithmetic) has been swept under your carpet for you by Python 3.2:
Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 15511210043330985984000000 / (479001600 * 6227020800)
5200300.0
>>> repr(15511210043330985984000000 / (479001600 * 6227020800))
'5200300.0'
>>> int(15511210043330985984000000 / (479001600 * 6227020800))
5200300
Python 3.1.3 (r313:86834, Nov 27 2010, 18:30:53) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 15511210043330985984000000 / (479001600 * 6227020800)
5200299.999999999
>>> repr(15511210043330985984000000 / (479001600 * 6227020800))
'5200299.999999999'
>>> int(15511210043330985984000000 / (479001600 * 6227020800))
5200299
I'm puzzled: presumably you used int() because you realised that it was producing a float answer. Why did you not take the (obvious?) next step of rounding it, e.g.
[3.1.3]
>>> int(round(15511210043330985984000000 / (479001600 * 6227020800)))
5200300
?
Related
I want to set precision (more in general the format) when printing a polynomial. For example:
>>> import numpy as np
>>> beta = np.asarray([-3.61380614191654e-09, 2.489464876955e-05, -0.0836384579176789, 143.213931472633])
>>> p = np.poly1d(beta)
>>> p
poly1d([-3.61380614e-09, 2.48946488e-05, -8.36384579e-02, 1.43213931e+02])
>>> print(p)
3 2
-3.614e-09 x + 2.489e-05 x - 0.08364 x + 143.2
>>> np.set_printoptions(precision=8) # this has no effect
>>> print(p)
3 2
-3.614e-09 x + 2.489e-05 x - 0.08364 x + 143.2
I would like to get, calling print with polynomial, something similar to:
3 2
-3.61380614e-09 x + 2.48946487e-05 x - 0.08363845 x + 143.21393147
[Edit]
I tried using numpy.polynomial as A. Donda suggest but I get a different behaviour:
Python 3.8.6 (default, Jan 27 2021, 15:42:20)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> beta = np.asarray([-3.61380614191654e-09, 2.489464876955e-05, -0.0836384579176789, 143.213931472633])
>>> p = np.polynomial.Polynomial(np.flip(beta))
>>> p
Polynomial([ 1.4321393147e+02, -8.3638457918e-02, 2.4894648770e-05,
-3.6138061419e-09], domain=[-1, 1], window=[-1, 1])
>>> print(p)
poly([ 1.4321393147e+02 -8.3638457918e-02 2.4894648770e-05 -3.6138061419e-09])
printing the polynomial using print(p) does not give me the expected result
[Edit2]
Ubuntu 20.10 has numpy 1.18.4. Instead, forcing a newer version (1.20.1) using pip3, I get the desired result.
The __str__ method of poly1d uses a custom function to format numbers:
def fmt_float(q):
s = '%.4g' % q
if s.endswith('.0000'):
s = s[:-5]
return s
So, you are right, it is not influenced by NumPy's printoptions.
But the documentation for poly1d says that it is "part of the old polynomial API" and one should better use numpy.polynomial:
>>> p = np.polynomial.Polynomial(np.flip(beta))
>>> p
Polynomial([ 1.432139e+02, -8.363846e-02, 2.489465e-05, -3.613806e-09], domain=[-1, 1], window=[-1, 1])
>>> print(p)
143.213931472633 - 0.0836384579176789·x¹ + 2.489464876955e-05·x² - 3.61380614191654e-09·x³
The np.flip is necessary because other than poly1d, Polynomial expects the coefficients by increasing order.
That seems to solve your concrete problem, getting the coefficients in high precision. However, Polynomial.__str__ still doesn't respect printoptions:
>>> np.set_printoptions(precision=3)
>>> print(p)
143.213931472633 - 0.0836384579176789·x¹ + 2.489464876955e-05·x² - 3.61380614191654e-09·x³
You could file an issue on the NumPy repository.
a = 15511210043330985984000000 # (25!)
b = 479001600 # (12!)
c = 6227020800 # (13!)
On dividing ans = int(a/(b*c)) or ans = int((a/b)/c) we get ans equal to 5200299 instead of 5200300
In Python 3.x / means floating point division and can give small rounding errors. Use // for integer division.
ans = a // (b*c)
Try using integer division instead of float division.
>>> 15511210043330985984000000 / (479001600 * 6227020800)
5200299.999999999
>>> 15511210043330985984000000 // (479001600 * 6227020800)
5200300
Your problem (not using integer arithmetic) has been swept under your carpet for you by Python 3.2:
Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 15511210043330985984000000 / (479001600 * 6227020800)
5200300.0
>>> repr(15511210043330985984000000 / (479001600 * 6227020800))
'5200300.0'
>>> int(15511210043330985984000000 / (479001600 * 6227020800))
5200300
Python 3.1.3 (r313:86834, Nov 27 2010, 18:30:53) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 15511210043330985984000000 / (479001600 * 6227020800)
5200299.999999999
>>> repr(15511210043330985984000000 / (479001600 * 6227020800))
'5200299.999999999'
>>> int(15511210043330985984000000 / (479001600 * 6227020800))
5200299
I'm puzzled: presumably you used int() because you realised that it was producing a float answer. Why did you not take the (obvious?) next step of rounding it, e.g.
[3.1.3]
>>> int(round(15511210043330985984000000 / (479001600 * 6227020800)))
5200300
?
Say i have
1009732533765201
and i want:
0x1009732533765201 which is
1155581383011619329
You can do this in programming languages with strings like this
int('1009732533765201',16)
but i want the pure math way. To convert 1009732533765201 to it's base16 of 1155581383011619329
I tried: int('1009732533765201',16) but this uses a string, and is slow for large numbers, i'm looking for a math angle only.
Here is a math way i know how to do it:
0x1009732533765201 = 1155581383011619329
Here is a python way to do it:
int('1009732533765201',16)
but i can only do the first math version manually. How can this be accomplished, converting 0x1009732533765201 without using a string to concatenating '0x' to '1009732533765201' and not using eval
Is there any way to take 1009732533765201, and convert it to the same ouput as 0x1009732533765201 to get its integer without using int('1009732533765201',16) my goal is to find a faster approach
ANSWERED BY PARTHIAN SHOT, here is the result of his approach which is exactly what i was looking for, a way to do this without int()
orig = 1009732533765201
num = orig
result = 0
i = 0
while num != 0:
result += (num % 10) * (16 ** i)
num //= 10
i += 1
print(orig, num, result, "%x" % (result))
1009732533765201 0 1155581383011619329 1009732533765201
As I said in my comment, Python knows, out of box, how to deal with base 16 numbers. Just go ahead and assign the base 16 value to a variable.
Here is an example:
Python 3.7.4 (default, Aug 12 2019, 14:45:07)
[GCC 9.1.1 20190605 (Red Hat 9.1.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> i=0x16
>>> i
22
>>> i=0xAA
>>> i
170
>>>
And as I said, that works for other bases, like base 2:
>>> i=0b1010
>>> i
10
>>>
And base 8:
>>> i=0o12
>>> i
10
>>>
The idea here is that we're looking at each digit of the original decimal number one at a time, from right to left, and multiplying it by 16 ** i instead of 10 ** i, then adding it to the new number.
The result is the equivalent of interpreting the original decimal representation of the number as if it were hexadecimal.
#!/usr/bin/env python
orig = 34029235
num = orig
result = 0
i = 0
while num != 0:
result += (num % 10) * (16 ** i)
num //= 10
i += 1
print(orig, num, result, "%x" % (result))
And running that code gets us...
bash$ ./main.py
(34029235, 0, 872583733, '34029235')
bash$
This code is a simple implementation of Fermat's Prime Factor. When I enter random 13, 14 15 digit integer to find the factor, depends on the input value, it produces the wrong result.
unit tested with product of two prime numbers of (7919) and prime numbers under 10000. It seems working well. However, when I tried with large integer of 13, 14, 15 digit numbers, depend on the input value, it produces wrong result.
def Prime_Factor(target):
a = int(math.sqrt(target))
b= a
while((a+b) <= target):
a = a + 1
b = math.sqrt(a**2 - target)
if((b % 1) == 0):
b = int(b)
print('a = ', a, ', b = ',b)
print('(a+b) = ,', (a+b), ', (a-b) = ', (a-b))
print('(a+b) * (a-b) = ', (a+b)*(a-b), end='')
if((a+b)*(a-b) == target):
print(' No Error Detected \n\n')
else:
print(' <> !=' , target, ' ERROR ******** \n\n')
exit
return
import math
Prime_Factor(9484756478341)
> Python 3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64)]
> Type "copyright", "credits" or "license" for more information.
> IPython 7.4.0 -- An enhanced Interactive Python.
> runfile('C:/Users/Paul/.spyder-py3/temp.py', wdir='C:/Users/Paul/.spyder- py3')
> a = 68579938 , b = 68510752
> (a+b) = , 137090690 , (a-b) = 69186
> (a+b) * (a-b) = 9484756478340 <> != 9484756478341 ERROR ********
Thank you everyone for the valuable comment. I've look into and found a few big integer packages for python such as gmpy2 etc. Death by truncation, indeed. Thank you for your help. cheers!
So everytime I try to use my Point.top() command I keep getting:
'int' object is not subscriptable
And this the code:
def top():
datalist = sorted(Point.dPoint.items(), key=lambda x: x[1][0], reverse=True)
t = 1
top = []
for l in datalist:
top.append(l[0].title()+": "+str(l[1][0])+(" point" if l[1][0] > 1 else " points"))
if t == 15:
break
t+=1
return top
This is inside the file and how it saves:
charles 45
tim 32
bob 67
I'm not sure why that error keeps happening. The code is suppose to get the top 15 people of who has the highest points. It would return this:
["Bob: 67 points", "Charles: 45 points", "Tim: 32 points"]
One of your variables is an int, and you're doing variable[0], which you can't do with an int.
Python 3.3.2 (default, Aug 25 2013, 14:58:58)
[GCC 4.2.1 Compatible FreeBSD Clang 3.1 ((branches/release_31 156863))] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 42
>>> a[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not subscriptable
>>> type(a)
<class 'int'>
>>>
I suggest to make code more explicit, e.g.:
def top():
player_points_couples = sorted(Point.dPoint.items(), key=lambda player_point_couple: player_point_couple[1][0], reverse=True)
top_players_number = 1
top_players = []
for player, points in player_points_couples :
top_players.append(player.title()+": "+str(points[0])+(" point" if points[0] > 1 else " points"))
if top_players_number == 15:
break
top_players_number += 1
return top_players
In this way you'll find the strange expressions:
player_point_couple[1][0]
...
points[0]
which mean "the first element of 'points'"... but 'points' is a number, no elements inside!
EDIT
Just to go into pythonic style:
def top():
from operator import itemgetter
player_points_couples = sorted(Point.dPoint.items(), key=itemgetter(1), reverse=True)
string_template_singular = "%s: %d point"
string_template_plural = "%s: %d points"
top_players = []
for player, points in player_points_couples[:15]:
string_template = string_template_plural if points > 1 else string_template_singular
top_players.append(string_template % (player.title(), points))
return top_players