wrong result on adition of numbers larger than epsilon using numpy.float128 - python

Considering that epsilon is the smallest number that you can add to one.
I'm getting 1 instead of 1+epsilon when I perform the addition and print the result.
I've implemented a getEpsilon function. I added a print statement for debugging.
The function is implemented as follows:
def getEpsilon():
a = np.float128(1)
b = np.float128(1)
c = np.float128(2)
while a + b != a:
b = b / c
d = a+b
print (F"b={b:3.50f}, d={d:3.50f}")
return b * c
After some iterations of the while loop the value of d is just 1, but a + b != a still evaluates as True.
This is the output:
b=0.5000000000000000000000000, d=1.5000000000000000000000000
b=0.2500000000000000000000000, d=1.2500000000000000000000000
...
b=0.0000000000000004440892099, d=1.0000000000000004440892099
b=0.0000000000000002220446049, d=1.0000000000000002220446049
b=0.0000000000000001110223025, d=1.0000000000000000000000000
b=0.0000000000000000555111512, d=1.0000000000000000000000000
...
b=0.0000000000000000001084202, d=1.0000000000000000000000000
b=0.0000000000000000000542101, d=1.0000000000000000000000000
Why does a + b != a have a different behavior than d = a+b
It looks like some operation is done with 64 bits instead.
If I repeat it with the float64 equivalent type the result is (last 2 lines):
b=0.0000000000000002220446049, d=1.0000000000000002220446049
b=0.0000000000000001110223025, d=1.0000000000000000000000000

Related

adding variable to python function using other variable

I would like pass the variables into the function that uses range(). How do I pass variable C that has more then one number via one variable. Something like range(5, 10, 2)?
Here is my example code:
a = 0
b = 10
c = 2
def num_count(a, b, c):
for number in range(c):
a += b
print("New Count is: {0}".format(a))
I tried passing it as a string and converting it to an integer as well as by using a list. Nothing worked.
you can pass in the range like you mentioned with only a small change to the
for loop
a = 0
b = 10
c = range(5, 10, 2)
def num_count(a, b, c):
for number in c:
a += b
print("New Count is: {0}".format(a))
num_count(a,b,c)
or, as khelwood* mentioned, pass in a list/tuple and expand it with *
a = 0
b = 10
c = (5, 10, 2)
def num_count(a, b, c):
for number in range(*c):
a += b
print("New Count is: {0}".format(a))
num_count(a,b,c)
both output 30 which is expected

Median of three, pivot

I'm looking for the median of three, using this for a pivot in a QuickSort. I would not like to import any statistics library because I believe it creates a bit of overhead which I would like to reduce as much as possible.
def median(num_list):
if (num_list[0] > num_list[len(num_list) - 1]) and (num_list[0] < num_list[int(len(num_list)//2)]):
return num_list[0]
elif (num_list[int(len(num_list)//2)] > num_list[len(num_list) - 1]) and (num_list[0] > num_list[int(len(num_list)//2)]):
return num_list[int(len(num_list)//2)]
else:
return num_list[len(num_list) - 1]
this seems to be returning the last else statement every time, I'm stumped...
In Quicksort you do not usually want just to know the median of three, you want to arrange the three values so the smallest is in one spot, the median in another, and the maximum in yet another. But if you really just want the median of three, here are two ways, plus another that rearranges.
Here's a short way to find the median of a, b, and c.
return a + b + c - min(a, b, c) - max(a, b, c)
If you want only comparisons, and to get what may be the quickest code, realize that three comparisons may need to be executed but you want to try for only two. (Two comparisons can handle four cases, but there are six arrangements of three objects.) Try
if a < b:
if b < c:
return b
elif a < c:
return c
else:
return a
else:
if a < c:
return a
elif b < c:
return c
else:
return b
If you want to rearrange the values so a <= b <= c,
if a > b:
a, b = b, a
if b > c:
b, c = c, b
if a > b
a, b = b, a
return b
Let Python do the work for you. Sort the three elements, then return the middle one.
def median(num_list):
return sorted([num_list[0], num_list[len(num_list) // 2], num_list[-1]])[1]
Using min and max:
>>> numlist = [21, 12, 16]
>>> a, b, c = numlist
>>> max(min(a,b), min(b,c), min(a,c))
16
>>>
Going out on a limb - I have a functional streak so here is the itertools equivalent, even though it means importing a module
>>> import itertools
>>> numlist = [21, 12, 16]
>>> z = itertools.combinations(numlist, 2)
>>> y = itertools.imap(min, z)
>>> max(y)
16

Middle value using python 3

UPDATED
a = int(input("Give a value: "))
b = int(input("Give a value: "))
c = int(input("Give a value: "))
def middle(a, b ,c) :
m = min(a,b,c)
M = max(a,b,c)
return a+b+c-m-M
This is where im at. It takes my numbers into the data. How would I get it to display the middle one?! Sorry I'm so terrible at this. Way in over my head on this intro course. #CommuSoft #Zorg #paxdiablo and everyone else
Like others mentioned, you're missing a colon, but for simplicity sake:
def middle(a, b, c):
return sorted([a, b, c])[1]
You should put a colon (:) on the first line (def) as well.
This works for the online python environment:
def input(a, b, c) :
if a <= b <= c or c <= b <= a :
return b
elif b <= a <= c or c <= a <= b :
return a
else:
return c
Furthermore it is more advisable to make use of min and max I guess. Min and max are sometimes directly supported by a CPU and there are implementations that avoid branching (if-then-else's):
def input(a, b, c) :
m = min(a,b,c)
M = max(a,b,c)
return a+b+c-m-M
or:
def input(a, b, c) :
return min(max(a,b),max(b,c),max(a,c))
The last one is also numerically stable.
In most cases if-then-else clauses should be avoided. They reduce the amount of pipelining although in interpreted languages this might not increase performance.
Based on the comments, I guess you want to write an interactive program. This can be done like:
def middle(a, b, c) : #defining a method
return min(max(a,b),max(b,c),max(a,c))
a = int(input("Give a value: "))
b = int(input("Give b value: "))
c = int(input("Give c value: "))
print("The requested value is ")
print(middle(a,b,c)) #calling a method
Defining a method will never result in Python using that method. The a, b and c in the def block are not the a, b and c in the rest of your program. These are "other variables that happen to have the same name". In order to call a method. You write the methods name and between brackets the parameters with which you wish to call your method.
Post your full syntax error (or any other full traceback) whenever you're having trouble.
And your def line needs a colon.
You could do:
def middle(a,b,c):
s={a,b,c}
s-={min(s),max(s)}
return s.pop()
What this does:
Create a set of the unduplicated values:
>>> a,b,c=1,2,3
>>> s={a,b,c}
>>> s
{1, 2, 3}
Remove the max and the min, leaving the middle:
>>> s-={min(s), max(s)}
>>> s
{2}
Pop the only remaining value:
>>> s.pop()
2

python generators/ variable [duplicate]

This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 9 years ago.
2 questions...
1) I am trying to wrap my brain around this...
I am to understand that variables can take values using such code syntax as this:
a ,b = 2, 3
and that this would be the same as coding:
a = 2
b = 3
I hope this is correct.
So here is my puzzlement. I have the following code using a generator:
def fibonacci_generator() :
a = b = 1
while True :
yield a
a , b = b , a + b
fib = fibonacci_generator()
for i in fib :
if i > 100 :
break
else :
print ('Generated: ', i)
print (next(fib))
(yes this is code from a python learning book)
If I were to rewrite this code and instead assign my a and b variables like so:
yield a
a = b
b = a + b
then I get different returns for a.
I am not understanding why this is??? Super frustrated about it!
2) When I run the code as written the first time above, I get the number 233 printed at the end. I also cannot figure out why??!!
In this code:
a, b = b, a + b
a is set to b, and b is set to a+b.
In this code:
a = b
b = a + b
a is set to b, and b is afterwards set to a+b. But since a is already set to b, then b is in fact set to b+b.
a , b = b , a + b
is not the same as
a = b
b = a + b
Because, when you say
a, b = b, a + b
It will first prepare the values on the right side b, a + b and assign them to the variables on the left.
Python computes the right hand side first and then assigns the value (or unpacks it) on the left hand side. So, in the example:
a, b = b, a+b
compared to:
a = b
b = a + b
You have different values for a when you go to compute a + b. In the second example, when you compute a + b it is equivalent to computing b + b!
You are probably missing the flow of data.
a = b ...eqI
b = a+b ...eqII
here, before executing b eqII, a has already stored bas a value of itself. Now when yow try execute b of eqII it comes like b=b+b. Because after executing eqI when it comes to eqII, a is bnow.
But in python you can avoid this conflict if you try a, b = b, a+b.
For your second question:
I am not sure about your code but this one will work fine in the sense of your code...
a = b = 1
while True :
a , b = b , a + b
if a and b > 100:
break
else: print a, b
try it !!
In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. Because that you get different results
a, b = b, a+b
This line computes b and a+b before performing any assignment. Strictly speaking, it computes a tuple (b, a+b) and then unpacks the elements of the tuple to assign them to a and b.
a = b
b = a+b
This assigns a, then computes a+b using the new value of a.

Python programming beginner difficulties

I am trying to write a program in Python, but I am stuck in this piece of code:
def function():
a=[3,4,5,2,4]
b=1
c=0
for x in range(5):
if a[x-1]>b:
c=c+1
return c
print(function())
It gives me value 1 instead of 5. Actually the function I am trying to write is a little bit more complicated, but the problem is actually the same, it doesn't give me the right result.
def result():
r=[0]*len(y)
a=2
b=an_integer
while b>0:
for x in range(len(y)) :
if y[x-1] > 1/a and b>0:
r[x-1]=r[x-1]+1
b=b-1
a=a+1
return r
print(result())
v is a list of values smaller than 1 and b has an integer as value. If some values x in v are bigger than 1/a then the values x in r should get 1 bigger, then it should repeat a=a+1 until b becomes 0. I want this function to give a result of the type for ex. [7,6,5,4,3] where the sum of the elements in this list is equal to b.
Sometimes it gives me the right value, sometimes not and when the elements in v are equal for example v=[0.33333,0.33333,0.33333] it gets stuck and doesn't give me a result.
I don't know what I am doing wrong !
Your return statements are incorrectly indented. You want to return after the loop ends, not inside the loop.
def function():
a = [3, 4, 5, 2, 4]
b = 1
c = 0
for x in range(5):
if a[x-1] > b:
c = c + 1
return c
Also, a couple of optimizations to the code:
def function(a, b):
c = 0
for x in a:
if x > b:
c += 1
return c
or further:
def function(a, b):
return sum(x > b for x in a)
return; only inside the fun in the end it.
and name the Variable v

Categories

Resources