Reputation: 1
this code is supposed to take slope (m) and y-intercept (b) of two lines and checks if these two line hit each other or not. the problem is my while loop is infinite although I have condition and break statement
print("enter the first m: ")
m = input() # m = slope
print("enter the first b: ")
b = input() # b = y-intercept
print("enter the second m: ")
m1 = input()
print("enter the second b: ")
b1 = input()
sub_m = int(m) - int(m1) #sub = subtract
sub_b = int(b) - int(b1)
if (sub_m == 0):
print("parallel")
x = float(-sub_b / sub_m)
r = round(x, 1)
i = 0.0
while i != r:
print(r, i)
if (i == r):
print("\nhit piont: ", i)
break
if (sub_m > 0 and sub_b > 0):
i -= 0.1
elif (sub_m < 0 and sub_b < 0):
i -= 0.1
else:
i += 0.1
Upvotes: 0
Views: 1799
Reputation: 4838
Everyone here seems to be adamant on using some fancy tricks to make floating comparison works. Why not just multiply it all by 10 and get rid of floats altogether? :-)
I don't know if it is the fastest solution but it should have less corner cases.
i = 0
while True: # <- condition removed to allow the "hit point" if to work
print(r, i / 10)
if (i == r * 10):
print("\nhit piont: ", i / 10)
break
if (sub_m > 0 and sub_b > 0):
i -= 1
elif (sub_m < 0 and sub_b < 0):
i -= 1
else:
i += 1
Upvotes: 1
Reputation: 323
Running this in my debugger showed that you're getting floating point representation errors. This means that although technically you should be getting numbers perfectly rounded to 1 decimal given that you're applying increments of 0.1, in reality this isn't the case:
As you can see, r = -2.0
and i = -2.00...4
, thus at no point is r == i
.
You can fix this by adding another round statement at the end:
print("enter the first m: ")
m = input() # m = slope
print("enter the first b: ")
b = input() # b = y-intercept
print("enter the second m: ")
m1 = input()
print("enter the second b: ")
b1 = input()
sub_m = int(m) - int(m1) #sub = subtract
sub_b = int(b) - int(b1)
if (sub_m == 0):
print("parallel")
x = float(-sub_b / sub_m)
r = round(x, 1)
i = 0.0
while i != r:
print(r, i)
if (sub_m > 0 and sub_b > 0):
i -= 0.1
elif (sub_m < 0 and sub_b < 0):
i -= 0.1
else:
i += 0.1
i = round(i, 1) # <- this
print(f"Hit pt: {i}")
HOWEVER: This is still error prone, and I recommend finding a way to avoid if i==r
altogether in the code. If i
is lower than r
, exit the loop when it finally becomes bigger, and viceversa. Its best practice to avoid using the ==
condition when comparing floats, and to find a way to use <=
and >=
.
Upvotes: 0
Reputation: 238
First of all, your while loop breaking condition contradicts your if() break
condition. so it will never get to match the if
condition. So it will never print hit point
, because it will break the while loop when l==r
, either it will never be l==r
because of precision and loop infinite, so in both situations if
condition never match. And comparing a floating value to break
a loop is not ideal.
Upvotes: 0
Reputation: 1217
This is a question of granularity and floating-point precision. You're incrementing i in steps of 0.1 and then checking, at each step, if i == r
. But what if r is not an integer multiple of 0.1? Then i will never exactly equal r, and your break
will never be triggered.
By the way, your while
condition and your if
condition are mutually exclusive; if i and r are equal, you never enter the loop, and consequently won't have to/be able to break
out of it. What you want is probably a genuine infinite loop with while True
.
Upvotes: 0