0

Heres my code run it:

def mySeq(n):
    seq = 1

    currentNumber = 1
    tickIn = False
    for x in range(0,n):
        if (tickIn == True):
            currentNumber = (currentNumber / 4)
            tickIn = False
        else:
            currentNumber = currentNumber + 6
            tickIn = True
        print(currentNumber)

Output of mySeq(75):

mySeq(75) 7 1.75 7.75 1.9375 7.9375 1.984375 7.984375 1.99609375 7.99609375 1.9990234375 7.9990234375 1.999755859375 7.999755859375 1.99993896484375 7.99993896484375 1.9999847412109375 7.9999847412109375 1.9999961853027344 7.999996185302734 1.9999990463256836 7.999999046325684 1.999999761581421 7.999999761581421 1.9999999403953552 7.999999940395355 1.9999999850988388 7.999999985098839 1.9999999962747097 7.99999999627471 1.9999999990686774 7.999999999068677 1.9999999997671694 7.999999999767169 1.9999999999417923 7.999999999941792 1.999999999985448 7.999999999985448 1.999999999996362 7.999999999996362 1.9999999999990905 7.9999999999990905 1.9999999999997726 7.999999999999773 1.9999999999999432 7.999999999999943 1.9999999999999858 7.999999999999986 1.9999999999999964 7.9999999999999964 1.9999999999999991 7.999999999999999 1.9999999999999998 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0 2.0 8.0

Now why does it do this to a limit but then break into whole numbers? - Mathematically? I've tried this with another pair of commons and it produces the same type of output reaching a LIMIT.

sam yellow
  • 31
  • 3
  • This is more of a math question than a programming question. – internet_user Jan 30 '18 at 21:25
  • 2
    @PatrickArtner: `decimal.Decimal` is still floating point. It's just decimal floating point. [The same precision issues arise with `decimal.Decimal`.](https://ideone.com/8pwClD) – user2357112 Jan 30 '18 at 21:29
  • @user2357112 My bad, confused it with bignum for integers wich can go arbritary big. so no full precision decimalnumber module for this? – Patrick Artner Jan 30 '18 at 21:44
  • 1
    @PatrickArtner: `decimal.Decimal` offers configurable precision, but I don't believe there's an option to give results as much precision as necessary to represent the exactly correct mathematical value. – user2357112 Jan 30 '18 at 21:49
  • 1
    @PatrickArtner, @user2357112, there just can't be "enough precision" in the general case because there are [irrational numbers](https://en.wikipedia.org/wiki/Irrational_number). For example, how many digits do you need to exactly represent something like `π` or to make things a bit worse `π^e`? – SergGr Jan 30 '18 at 22:04
  • @SergGr: For addition, subtraction, and multiplication, "enough precision" always exists, and it also exists for many cases of division (including all cases involved in this question). [Java's `BigDecimal`](https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html) takes an approach of always giving exact results unless you explicitly request an inexact operation; Python's `decimal.Decimal` could have been designed similarly. – user2357112 Jan 30 '18 at 23:10
  • @user2357112, Ok what is "enough precision" for `π+e`? My claim is that if you start with irrational numbers there can never be enough precision. If you start with rational numbers and stay only inside the rational field, then obviously doing calculations as fractions of something like `BigInteger` (i.e. using the ultimate representation of any rational number) you can achieve exact results. – SergGr Jan 30 '18 at 23:14
  • @SergGr: It's not possible to start with an irrational number. For any possible `Decimal` inputs to `+`, "enough precision" exists. `π` is not a possible `Decimal` value in the first place. – user2357112 Jan 30 '18 at 23:41
  • For arithmetic over ℝ, there is no such thing as "enough precision" even to take inputs, before you try to perform a single operation, but I'm not talking about ℝ. I'm talking about operations on `Decimal` objects. – user2357112 Jan 30 '18 at 23:47

2 Answers2

3

(Note: I reopened this because it really isn't a question about floating-point behavior.)

Well, supposing it will eventually oscillate between two numbers, LO and HI, then they must satisfy the equations:

LO = HI / A
HI = LO + B

For the example you gave, A=4 and B=6. Some straightforward algebra on those equations gives:

LO = B/(A-1)
HI = LO + B

So, for your example, LO = B/(A-1) = 6/(4-1) = 2 and then HI = LO + B = 2 + 6 = 8. Which are the numbers you eventually see.

Now suppose you start with a number N = LO + EPSILON. After two iterations starting with your second operation, the loop first adds B and then divides by A. And:

(N+B)/A =
(LO + EPSILON + B)/A =
(B/(A-1) + B + EPSILON)/A =
(B/(A-1) + B*(A-1)/(A-1) + EPSILON)/A =
((B+B*(A-1))/(A-1) + EPSILON)/A =
(A*B/(A-1) + EPSILON)/A =
B/(A-1) + EPSILON/A =
LO + EPSILON/A

So, provided A > 1, the result is a factor of A closer to LO than the number you started with. For example, at the point you got 1.75, that was 0.25 less than 2, and two steps later you got 1.9375, which is 0.0625 less than 2, which is 0.25/4. Two steps after that, the result will be 0.0625/4 = 0.015625 less than 2 = 1.984375.

And so on. Eventually it gets so close to 2 that the difference can't show up in a finite-precision float.

You can work out for yourself the similar dance needed to see what happens to HI after two steps on it :-)

Tim Peters
  • 67,464
  • 13
  • 126
  • 132
0

From the looks of it. 1.9999999999999964 7.9999999999999964 1.9999999999999991 7.999999999999999  Keeps coming closer to 1.

Also, at 7.999999999999999 point you will reach the precision of python double. 15 digits to the right of the decimal point.

Ashwath Narayan
  • 143
  • 1
  • 1
  • 10