What I wanted to do:
Paradox: Suppose Peter Parker were running to catch a bus. To reach it, he’d first need to get halfway there. Before that, he’d need to get a quarter of the way there……before a quarter, an eighth; before an eighth, a 16th; and so on. Since the distance can be halved infinitely, he’d be trying to complete an infinite number of tasks… WHICH WOULD BE LOGICALLY IMPOSSIBLE!
I tried to to resolve this paradox using Python
I have some questions:
How can I get a number to have no limitations with decimals? Python limits the numbers of decimals, I think to 12, How to make that number infinite?
Aparrently there is no way to make the float decimals infinite, the closest I could get was using this
from decimal import Decimal
Is this the correct way of asking the user for an input in numbers?
Code modified
from decimal import Decimal
def infinite_loop():
x = 0;
number = Decimal(raw_input())
while x != number:
x = x + number
number = number/2
print x
infinite_loop()
What you ask is impossible. There are no "infinite precision" floating point values in the real world of finite computing systems. If there were, a single floating point value could consume all of the system's resources. pi * d? Ooops!! pi is infinite. There goes the system!
What you can do, however, is get arbitrary precision decimal values. They're still finite, but you can choose how much precision you want (and are willing to pay for). E.g.:
>>> from decimal import Decimal
>>> x = Decimal('1.' + '0' * 200)
>>> x
Decimal('1.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
Now you have 200 digits of precision. Not enough? Go 400. 800. However many you like. As long as that's a finite, practical value.
If you want "infinite" precision (e.g. a decimal number that be extended as far as you have memory for), either use Python's builtin module Decimal or for more heavy computation, mpmath:
import mpmath as mp
mp.mp.dps = 100
print mp.sqrt(mp.mpf(2))
>> 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573
Related
Why does the large number give me an integer (or at least no decimal points), but the smaller number give me a bunch of decimal points? Is the way I set the precision or declare the variables wrong?
import math
from mpmath import *
mp.prec=1000
x = 5431526412865007456
print mpf((x)/6)
ACTUAL OUTPUT: 905254402144167909.0
WANTED OUTPUT: 905254402144167909.3333333333333333333333(…)
x = 5431526413
print mpf((x)/6.)
OUTPUT: 905254402.16666662693023681640625
Try using mpf(x)/6 or mpf(x)/6.0. The reason your code didn't work is that it did the division using Python's normal rules, then converted it to a arbitrary-precision number, whereas this converts it first so the division is done using arbitrary-precision math.
Importing Fraction from fractions to give a fractional representation of a real number, but giving responses quite complicated which seems very simple by the paper-pen method.
Fractions(.2) giving answer 3602879701896397/18014398509481984,
which is 0.20000000000000001110223024625157, almost .2, but I want it to be simply 1/5.
I know there's limit() for this use, but what I simply required is smallest numerator and denominator which gives the exact real number bcoz I am dealing with a lot of numbers in a big range so i cant use same limit() argument for all.
You can use the Fraction class to represent 0.2, and you can access the numerator and denominator as follows:
>>> from fractions import Fraction
>>> f = Fraction(1, 5)
>>> f.numerator
1
>>> f.denominator
5
Hope it helps.
Your strange output results from float point problems. You can in certain cases overcome this by limiting the denominator with Fraction.limit_denominator(). This procedure can of course also cause rounding errors, if the real value of the denominator is larger than the threshold you use. The default value for this threshold is 1,000,000, but you can also use smaller values.
>>> import fractions
>>> print(fractions.Fraction(0.1))
3602879701896397/36028797018963968
>>> # lower the threshold to 1000
>>> print(fractions.Fraction(0.1).limit_denominator(1000))
1/10
>>> # alternatively, use a str representation as per documentation/examples
>>> print(fractions.Fraction('0.1'))
1/10
>>> # won't work for smaller fractions, use default of 1,000,000 instead
>>> print(fractions.Fraction(0.00001).limit_denominator(1000))
0
>>> print(fractions.Fraction(0.00001).limit_denominator())
1/100000
Of course, as explained in the first sentence, there are precision limitations due to the way float numbers are stored. If you have numbers in the magnitude of 10^9, you won't get an accurate representation of 10 digits in the fractional part as
a = 1234567890.0987654321
print(a)
demonstrates. But you might ask yourself, if you really need an accuracy of 10^-15, if your input doesn't reflect this accuracy. If you want to have a higher precision, you have to use the decimal module right from the start with increased precision level throughout all mathematical operations. Even better is to take care of numerators and denominators as integer values from the beginning - in Python integer values are theoretically not restricted in size
I would like to generate uniformly distributed random numbers between 0 and 0.5, but truncated to 2 decimal places.
without the truncation, I know this is done by
import numpy as np
rs = np.random.RandomState(123456)
set = rs.uniform(size=(50,1))*0.5
could anyone help me with suggestions on how to generate random numbers up to 2 d.p. only? Thanks!
A float cannot be truncated (or rounded) to 2 decimal digits, because there are many values with 2 decimal digits that just cannot be represented exactly as an IEEE double.
If you really want what you say you want, you need to use a type with exact precision, like Decimal.
Of course there are downsides to doing that—the most obvious one for numpy users being that you will have to use dtype=object, with all of the compactness and performance implications.
But it's the only way to actually do what you asked for.
Most likely, what you actually want to do is either Joran Beasley's answer (leave them untruncated, and just round at print-out time) or something similar to Lauritz V. Thaulow's answer (get the closest approximation you can, then use explicit epsilon checks everywhere).
Alternatively, you can do implicitly fixed-point arithmetic, as David Heffernan suggests in a comment: Generate random integers between 0 and 50, keep them as integers within numpy, and just format them as fixed point decimals and/or convert to Decimal when necessary (e.g., for printing results). This gives you all of the advantages of Decimal without the costs… although it does open an obvious window to create new bugs by forgetting to shift 2 places somewhere.
decimals are not truncated to 2 decimal places ever ... however their string representation maybe
import numpy as np
rs = np.random.RandomState(123456)
set = rs.uniform(size=(50,1))*0.5
print ["%0.2d"%val for val in set]
How about this?
np.random.randint(0, 50, size=(50,1)).astype("float") / 100
That is, create random integers between 0 and 50, and divide by 100.
EDIT:
As made clear in the comments, this will not give you exact two-digit decimals to work with, due to the nature of float representations in memory. It may look like you have the exact float 0.1 in your array, but it definitely isn't exactly 0.1. But it is very very close, and you can get it closer by using a "double" datatype instead.
You can postpone this problem by just keeping the numbers as integers, and remember that they're to be divided by 100 when you use them.
hundreds = random.randint(0, 50, size=(50, 1))
Then at least the roundoff won't happen until at the last minute (or maybe not at all, if the numerator of the equation is a multiple of the denominator).
I managed to find another alternative:
import numpy as np
rs = np.random.RandomState(123456)
set = rs.uniform(size=(50,2))
for i in range(50):
for j in range(2):
set[i,j] = round(set[i,j],2)
This question already has answers here:
Python cos(90) and cos(270) not 0
(3 answers)
Closed 9 years ago.
Is there a way to get the exact Tangent/Cosine/Sine of an angle (in radians)?
math.tan()/math.sin()/math.cos() does not give the exact for some angles:
>>> from math import *
>>> from decimal import Decimal
>>> sin(pi) # should be 0
1.2246467991473532e-16
>>> sin(2*pi) # should be 0
-2.4492935982947064e-16
>>> cos(pi/2) # should be 0
6.123233995736766e-17
>>> cos(3*pi/2) # 0
-1.8369701987210297e-16
>>> tan(pi/2) # invalid; tan(pi/2) is undefined
1.633123935319537e+16
>>> tan(3*pi/2) # also undefined
5443746451065123.0
>>> tan(2*pi) # 0
-2.4492935982947064e-16
>>> tan(pi) # 0
-1.2246467991473532e-16
I tried using Decimal(), but this does not help either:
>>> tan(Decimal(pi)*2)
-2.4492935982947064e-16
numpy.sin(x) and the other trigonometric functions also have the same issue.
Alternatively, I could always create a new function with a dictionary of values such as:
def new_sin(x):
sin_values = {math.pi: 0, 2*math.pi: 0}
return sin_values[x] if x in sin_values.keys() else math.sin(x)
However, this seems like a cheap way to get around it. Is there any other way? Thanks!
It is impossible to store the exact numerical value of pi in a computer. math.pi is the closest approximation to pi that can be stored in a Python float. math.sin(math.pi) returns the correct result for the approximate input.
To avoid this, you need to use a library that supports symbolic arithmetic. For example, with sympy:
>>> from sympy import *
>>> sin(pi)
0
>>> pi
pi
>>>
sympy will operate on an object that represents pi and can give exact results.
When you're dealing with inexact numbers, you need to deal with error explicitly. math.pi (or numpy.pi) isn't exactly π, it's, e.g., the closest binary rational number in 56 digits to π. And the sin of that number is not 0.
But it is very close to 0. And likewise, tan(pi/2) is not infinity (or NaN), but huge, and asin(1)/pi is very close to 0.5.
So, even if the algorithms were somehow exact, the results still wouldn't be exact.
If you've never read What Every Computer Scientist Should Know About Floating-Point Arithmetic, you should do so now.
The way to deal with this is to use epsilon-comparisons rather than exact comparisons everywhere, and explicitly round things when printing them out, and so on.
Using decimal.Decimal numbers instead of float numbers makes this easier. First, you probably think in decimal rather than binary, so it's easier for you to understand and make decisions about the error. Second, you can explicitly set precision and other context information on Decimal values, while float are always IEEE double values.
The right way to do it is to do full error analysis on your algorithms, propagate the errors appropriately, and use that information where it's needed. The simple way is to just pick some explicit absolute or relative epsilon (and the equivalent for infinity) that's "good enough" for your application, and use that everywhere. (You'll probably also want to use the appropriate domain-specific knowledge to treat some values as multiples of pi instead of just raw values.)
I am working on a program that stores numbers as floats which I eventually write to a file as currency. I am currently using the round() function to round it to 2 decimals, but the business area would like me to round to the next penny no matter what the third decimal is. For example:
x = 39.142
In this case I am trying to get x to round up to 39.15. Obviously when I do the round function I get 39.14...
>>> round(x, 2)
39.14
Is there a way I can always round up to the next penny? I should mention that the numbers I am dealing with are printed to the file as currency.
Using the decimal module:
import decimal
D = decimal.Decimal
cent = D('0.01')
x = D('39.142')
print(x.quantize(cent,rounding=decimal.ROUND_UP))
# 39.15
Decimals have many options for rounding. The options and their meanings can be found here.
if you want to write it in cents, you could use int(x*100+.5) to get cents integer from float dollars.
Very late to this, but in case anyone wants a simple one-liner in Python 3:
import math
x_rounded = math.ceil(x*100) / 100