How to get value for 0.5^(5000) in Python3? - python

Current I want to calculate the value of a=0.5**5000. I knowa is very small value, but I need use a to multiply b, where b = 5000!, a very large value.
But when I calculate value of a=0.5^5000, the result is 0. Does anyone have a good method to solve this problem? Thanks!

I need use a to multiply b, where b = 5000!
I'd just divide 5000! by 25000 or shift it:
from math import factorial
print(factorial(5000) // 2**5000)
print(factorial(5000) >> 5000)
Output:
299375336...(more than 14000 digits)...080261230
Or as #wim points out, fractions.Fraction would be exact:
print(Fraction(factorial(5000), 2**5000))
Output:
958001075...(more than 14000 digits)...568359375/32
Which in decimal notation is:
299375336...(more than 14000 digits)...080261230.46875
So in this case that gives us only five more digits of precision, not much compared to already over 14000. But for example for 5!/25 it would be 3.75 instead of 3, quite a big difference. Then again, this small number (if you're using it as well) might be insignificant in what you're doing overall. Which we don't know because you only told us about this tiny part of your attempt to do whatever it is you're actually after.

Try the decimal module:
>>> from decimal import Decimal
>>> print(Decimal("0.5") ** 5000)
7.079811261048172892385615159E-1506
>>>

Here's an alternative answer using the mpmath library:
import mpmath
a = mpmath.power(0.5, 5000)
b = mpmath.factorial(5000)
c = mpmath.fmul(a, b)
print(a)
print(b)
print(c)
That includes the other calculations that you mentioned.
Output:
7.0798112610481728923856151586941e-1506
4.2285779266055435222010642002336e+16325
2.9937533623001661362907254353912e+14820

Use Decimal :
from decimal import Decimal
if __name__ == '__main__':
a = Decimal(str(0.5)) ** Decimal(str(5000))
print(a)
7.079811261048172892385615159E-1506

Related

how can i do calibration for the numbers after a comma in scipy basinhopping? [duplicate]

Using Python 2.7 how do I round my numbers to two decimal places rather than the 10 or so it gives?
print "financial return of outcome 1 =","$"+str(out1)
Use the built-in function round():
>>> round(1.2345,2)
1.23
>>> round(1.5145,2)
1.51
>>> round(1.679,2)
1.68
Or built-in function format():
>>> format(1.2345, '.2f')
'1.23'
>>> format(1.679, '.2f')
'1.68'
Or new style string formatting:
>>> "{:.2f}".format(1.2345)
'1.23
>>> "{:.2f}".format(1.679)
'1.68'
Or old style string formatting:
>>> "%.2f" % (1.679)
'1.68'
help on round:
>>> print round.__doc__
round(number[, ndigits]) -> floating point number
Round a number to a given precision in decimal digits (default 0 digits).
This always returns a floating point number. Precision may be negative.
Since you're talking about financial figures, you DO NOT WANT to use floating-point arithmetic. You're better off using Decimal.
>>> from decimal import Decimal
>>> Decimal("33.505")
Decimal('33.505')
Text output formatting with new-style format() (defaults to half-even rounding):
>>> print("financial return of outcome 1 = {:.2f}".format(Decimal("33.505")))
financial return of outcome 1 = 33.50
>>> print("financial return of outcome 1 = {:.2f}".format(Decimal("33.515")))
financial return of outcome 1 = 33.52
See the differences in rounding due to floating-point imprecision:
>>> round(33.505, 2)
33.51
>>> round(Decimal("33.505"), 2) # This converts back to float (wrong)
33.51
>>> Decimal(33.505) # Don't init Decimal from floating-point
Decimal('33.50500000000000255795384873636066913604736328125')
Proper way to round financial values:
>>> Decimal("33.505").quantize(Decimal("0.01")) # Half-even rounding by default
Decimal('33.50')
It is also common to have other types of rounding in different transactions:
>>> import decimal
>>> Decimal("33.505").quantize(Decimal("0.01"), decimal.ROUND_HALF_DOWN)
Decimal('33.50')
>>> Decimal("33.505").quantize(Decimal("0.01"), decimal.ROUND_HALF_UP)
Decimal('33.51')
Remember that if you're simulating return outcome, you possibly will have to round at each interest period, since you can't pay/receive cent fractions, nor receive interest over cent fractions. For simulations it's pretty common to just use floating-point due to inherent uncertainties, but if doing so, always remember that the error is there. As such, even fixed-interest investments might differ a bit in returns because of this.
You can use str.format(), too:
>>> print "financial return of outcome 1 = {:.2f}".format(1.23456)
financial return of outcome 1 = 1.23
When working with pennies/integers. You will run into a problem with 115 (as in $1.15) and other numbers.
I had a function that would convert an Integer to a Float.
...
return float(115 * 0.01)
That worked most of the time but sometimes it would return something like 1.1500000000000001.
So I changed my function to return like this...
...
return float(format(115 * 0.01, '.2f'))
and that will return 1.15. Not '1.15' or 1.1500000000000001 (returns a float, not a string)
I'm mostly posting this so I can remember what I did in this scenario since this is the first result in google.
The best, I think, is to use the format() function:
>>> print("financial return of outcome 1 = $ " + format(str(out1), '.2f'))
// Should print: financial return of outcome 1 = $ 752.60
But I have to say: don't use round or format when working with financial values.
When we use the round() function, it will not give correct values.
you can check it using,
round (2.735) and round(2.725)
please use
import math
num = input('Enter a number')
print(math.ceil(num*100)/100)
print "financial return of outcome 1 = $%.2f" % (out1)
A rather simple workaround is to convert the float into string first, the select the substring of the first four numbers, finally convert the substring back to float.
For example:
>>> out1 = 1.2345
>>> out1 = float(str(out1)[0:4])
>>> out1
May not be super efficient but simple and works :)
Rounding up to the next 0.05, I would do this way:
def roundup(x):
return round(int(math.ceil(x / 0.05)) * 0.05,2)

How to fix floating point decimal to two places even if number is 2.00000

This is what I have:
x = 2.00001
This is what I need:
x = 2.00
I am using:
float("%.2f" % x)
But all I get is:
2
How can I limit the decimal places to two AND make sure there are always two decimal places even if they are zero?
Note: I do not want the final output to be a string.
This works:
'%.2f" % float(x)
Previously I answered with this:
How about this?
def fmt2decimals(x):
s = str(int(x*100))
return s[0:-2] + '.' + s[-2:]
AFAIK you can't get trailing zeros with a format specification like %.2f.
If you can use decimal (https://docs.python.org/2/library/decimal.html) instead of float:
from decimal import Decimal
Decimal('7').quantize(Decimal('.01'))
quantize() specifies where to round to.
https://docs.python.org/2/library/decimal.html#decimal.Decimal.quantize
Have you taken a look at the decimal module? It allows you to do arithmetic while maintaining the proper precision:
>>> from decimal import Decimal
>>> a = Decimal("2.00")
>>> a * 5
Decimal('10.00')
>>> b = Decimal("0.05")
>>> a * b
Decimal('0.1000')
Python also has a builtin "round" function: x = round(2.00001, 2) I believe is the command you would use.
Well, in Python, you can't really round to two zeroes without the result being a string. Python will usually always round to the first zero because of how floating point integers are stored. You can round to two digits if the second digit is not zero, though.
For example, this:
round(2.00001, 2)
#Output: 2.0
vs this:
round(2.00601, 2)
#Output: 2.01

how to round to higher 10's place in python

I have a bunch of floats and I want to round them up to the next highest multiple of 10.
For example:
10.2 should be 20
10.0 should be 10
16.7 should be 20
94.9 should be 100
I only need it to go from the range 0-100. I tried math.ceil() but that only rounds up to the nearest integer.
Thanks in advance.
from math import ceil
def ceil_to_tens(x):
return int(ceil(x / 10.0)) * 10
Edit: okay, now that I have an undeserved "Nice answer" badge for this answer, I think owe the community with a proper solution using the decimal module that does not suffer from these problems :) Thanks to Jeff for pointing this out. So, a solution using decimal works as follows:
from decimal import Decimal, ROUND_UP
def ceil_to_tens_decimal(x):
return (Decimal(x) / 10).quantize(1, rounding=ROUND_UP) * 10
Of course the above code requires x to be an integer, a string or a Decimal object - floats won't work as that would defeat the whole purpose of using the decimal module.
It's a pity that Decimal.quantize does not work properly with numbers larger than 1, it would have saved the division-multiplication trick.
>>> x = 16.7
>>> int( 10 * math.ceil(x/10.0))
The answers here are fraught with peril. For example 11*1.1 - 2.1 = 10.0, right? But wait:
>>> x = 11*1.1 - 2.1
>>> int(ceil(x / 10.0)) * 10
20
>>> x
10.000000000000002
>>>
You could try this
int(ceil(round(x, 12) / 10.0)) * 10
But choosing the number of decimal places to round to is really difficult as it is hard to predict how floating point noise accumulates. If it is really important to get this right all of the time, then you need to use fixed point arithmetic or Decimal.
If you're looking for another solution that doesn't involve float division, here's one that uses the modulus:
def ceil_to_tens_mod(x):
tmp = int(ceil(x))
mod10 = tmp % 10
return tmp - mod10 + (10 if mod10 else 0)
There's probably some way to simplify it, but there you go.

Calculating e (base of the natural log) to high precision in Python?

Is it possible to calculate the value of the mathematical constant, e with high precision (2000+ decimal places) using Python?
I am particularly interested in a solution either in or that integrates with NumPy or SciPy.
You can set the precision you want with the decimal built-in module:
from decimal import *
getcontext().prec = 40
Decimal(1).exp()
This returns:
Decimal('2.718281828459045235360287471352662497757')
This can also be done with sympy using numerical evaluation:
import sympy
print sympy.N(sympy.E, 100)
Using a series sum you could calculate it:
getcontext().prec = 2000
e = Decimal(0)
i = 0
while True:
fact = math.factorial(i)
e += Decimal(1)/fact
i += 1
if fact > 10**2000: break
But that's not really necessary, as what Mermoz did agrees just fine with it:
>>> e
Decimal('2.7182818284590452353602874713526624977572470936999595749669676
277240766303535475945713821785251664274274663919320030599218174135966290
435729003342952605956307381323286279434907632338298807531952510190115738
341879307021540891499348841675092447614606680822648001684774118537423454
424371075390777449920695517027618386062613313845830007520449338265602976
067371132007093287091274437470472306969772093101416928368190255151086574
637721112523897844250569536967707854499699679468644549059879316368892300
987931277361782154249992295763514822082698951936680331825288693984964651
058209392398294887933203625094431173012381970684161403970198376793206832
823764648042953118023287825098194558153017567173613320698112509961818815
930416903515988885193458072738667385894228792284998920868058257492796104
841984443634632449684875602336248270419786232090021609902353043699418491
463140934317381436405462531520961836908887070167683964243781405927145635
490613031072085103837505101157477041718986106873969655212671546889570350
354021234078498193343210681701210056278802351930332247450158539047304199
577770935036604169973297250886876966403555707162268447162560798826517871
341951246652010305921236677194325278675398558944896970964097545918569563
802363701621120477427228364896134225164450781824423529486363721417402388
934412479635743702637552944483379980161254922785092577825620926226483262
779333865664816277251640191059004916449982893150566047258027786318641551
956532442586982946959308019152987211725563475463964479101459040905862984
967912874068705048958586717479854667757573205681288459205413340539220001
137863009455606881667400169842055804033637953764520304024322566135278369
511778838638744396625322498506549958862342818997077332761717839280349465
014345588970719425863987727547109629537415211151368350627526023264847287
039207643100595841166120545297030236472549296669381151373227536450988890
313602057248176585118063036442812314965507047510254465011727211555194866
850800368532281831521960037356252794495158284188294787610852639810')
>>> Decimal(1).exp()
Decimal('2.7182818284590452353602874713526624977572470936999595749669676
277240766303535475945713821785251664274274663919320030599218174135966290
435729003342952605956307381323286279434907632338298807531952510190115738
341879307021540891499348841675092447614606680822648001684774118537423454
424371075390777449920695517027618386062613313845830007520449338265602976
067371132007093287091274437470472306969772093101416928368190255151086574
637721112523897844250569536967707854499699679468644549059879316368892300
987931277361782154249992295763514822082698951936680331825288693984964651
058209392398294887933203625094431173012381970684161403970198376793206832
823764648042953118023287825098194558153017567173613320698112509961818815
930416903515988885193458072738667385894228792284998920868058257492796104
841984443634632449684875602336248270419786232090021609902353043699418491
463140934317381436405462531520961836908887070167683964243781405927145635
490613031072085103837505101157477041718986106873969655212671546889570350
354021234078498193343210681701210056278802351930332247450158539047304199
577770935036604169973297250886876966403555707162268447162560798826517871
341951246652010305921236677194325278675398558944896970964097545918569563
802363701621120477427228364896134225164450781824423529486363721417402388
934412479635743702637552944483379980161254922785092577825620926226483262
779333865664816277251640191059004916449982893150566047258027786318641551
956532442586982946959308019152987211725563475463964479101459040905862984
967912874068705048958586717479854667757573205681288459205413340539220001
137863009455606881667400169842055804033637953764520304024322566135278369
511778838638744396625322498506549958862342818997077332761717839280349465
014345588970719425863987727547109629537415211151368350627526023264847287
039207643100595841166120545297030236472549296669381151373227536450988890
313602057248176585118063036442812314965507047510254465011727211555194866
850800368532281831521960037356252794495158284188294787610852639814')
The excellent pure-python library, Mpmath, will certainly do the trick.
The sole focus of this library is multi-precision floating-point arithmetic.
E.g., Mpath can evaluate e to arbitrary precision:
In [2]: from mpmath import *
# set the desired precision on the fly
In [3]: mp.dps=20; mp.pretty=True
In [4]: +e
Out[4]: 2.7182818284590452354
# re-set the precision (50 digits)
In [5]: mp.dps=50; mp.pretty=True
In [6]: +e
Out[6]: 2.7182818284590452353602874713526624977572470937
As an aside, Mpmath is also tightly integrated with Matplotlib.
I would think you could combine the info from these webpages:
http://en.wikipedia.org/wiki/Taylor_series
This gives you the familiar power series. Since you're working with large factorial numbers you should then probably work with gmpy which implements multi-precision arithmetic.
Using Sage:
N(e, digits=2000)

Operations for Long and Float in Python

I'm trying to compute this:
from scipy import *
3600**3400 * (exp(-3600)) / factorial(3400)
the error: unsupported long and float
Try using logarithms instead of working with the numbers directly. Since none of your operations are addition or subtraction, you could do the whole thing in logarithm form and convert back at the end.
Computing with numbers of such magnitude, you just can't use ordinary 64-bit-or-so floats, which is what Python's core runtime supports. Consider gmpy (do not get the sourceforge version, it's aeons out of date) -- with that, math, and some care...:
>>> e = gmpy.mpf(math.exp(1))
>>> gmpy.mpz(3600)**3400 * (e**(-3600)) / gmpy.fac(3400)
mpf('2.37929475533825366213e-5')
(I'm biased about gmpy, of course, since I originated and still participate in that project, but I'd never make strong claims about its floating point abilities... I've been using it mostly for integer stuff... still, it does make this computation possible!-).
You could try using the Decimal object. Calculations will be slower but you won't have trouble with really small numbers.
from decimal import Decimal
I don't know how Decimal interacts with the scipy module, however.
This numpy discussion might be relevant.
Well the error is coming about because you are trying to multiply
3600**3400
which is a long with
exp(-3600)
which is a float.
But regardless, the error you are receiving is disguising the true problem. It seems exp(-3600) is too big a number to fit in a float anyway. The python math library is fickle with large numbers, at best.
exp(-3600) is too smale, factorial(3400) is too large:
In [1]: from scipy import exp
In [2]: exp(-3600)
Out[2]: 0.0
In [3]: from scipy import factorial
In [4]: factorial(3400)
Out[4]: array(1.#INF)
What about calculate it step by step as a workaround(and it makes sense
to check the smallest and biggest intermediate result):
from math import exp
output = 1
smallest = 1e100
biggest = 0
for i,j in izip(xrange(1, 1701), xrange(3400, 1699, -1)):
output = output * 3600 * exp(-3600/3400) / i
output = output * 3600 * exp(-3600/3400) / j
smallest = min(smallest, output)
biggest = max(biggest, output)
print "output: ", output
print "smallest: ", smallest
print "biggest: ", biggest
output is:
output: 2.37929475534e-005
smallest: 2.37929475534e-005
biggest: 1.28724174494e+214

Categories

Resources