;------------------------------------------------------------------------------- ; ; Example of runaway simple FP computation, by William Kahan (_gory_ details in ref. 6 below) ; ; Given u_0 = 2 and u_1 = -4 we then compute terms of the series ; ; u_[n] = 111 - 1130/(u[n-1]) + 3000/(u[n-1]*u[n-2]) ; ; where n > 1 clearly. ; ;------------------------------------------------------------------------------- ; ; Some readings for those interessed ; ; 1 ) IEEE 754-2008 - IEEE Standard for Floating-Point Arithmetic ; https://standards.ieee.org/standard/754-2008.html ; ; 2 ) Formal Verification of Floating-Point Hardware Design ; https://www.springer.com/us/book/9783319955124 ; ; 3 ) Handbook of Floating-Point Arithmetic ; https://www.springer.com/us/book/9783319765259 ; ; 4 ) The Art of Computer Programming ; https://cs.stanford.edu/~knuth/taocp.html ; ; 5 ) Oral history interview with Donald E. Knuth ; Charles Babbage Institute, 2001 ; https://conservancy.umn.edu/handle/11299/107413 ; ; 6 ) How Futile are Mindless Assessments of Roundoff in Floating-Point Computation ? ; Prof William Kahan ; https://people.eecs.berkeley.edu/~wkahan/Mindless.pdf ; ; ; No fancy arc-hyperbolic function, no exponentiation of some transcendental value, ; no eigenvalues of some large ill-conditionned matrix. Computation is trivial and ; only uses values within "everyday life range", not 1.068401397e-153 or 2.60897461e+267 ; ; OK then, fasten your belt guys. Local $u = [2.0, -4.0, 0] ; respectively u_0, u_1, u_2 (u_2 hasn't been assigned a value yet) ConsoleWrite(StringFormat("\tU n-2\t\t\tU n-1\t\t\tU n\n")) For $i = 1 To 25 $u[2] = 111 - 1130 / $u[1] + 3000 / ($u[1] * $u[0]) ConsoleWrite(StringFormat("%+20.16f\t%+20.16f\t%+20.16f\n", $u[0], $u[1], $u[2])) $u[0] = $u[1] $u[1] = $u[2] Next ; ; Try using the basic Windows calc to check by yourself and ; you'll see that the asymptotic result is clearly 6, not 100 ; ; Deceptive isn't it? ; And you own a state-of-the-art, multi-billion transistors, multi-GHz, costly processor... ; ; Don't use that to compute the trajectory of your crew to Mars! ; ConsoleWrite(@LF & @LF) ; ; I see your point: you're thinking: ; "If I use an unbounded precision arithmetic library, I'll get them there, slowly but safely." ; ; Well, so see them watch out Mars hopelessly drifting away: ; #include "..\include\BigNum.au3" Local $v = [2, -4, ""] ; respectively v_0, v_1, v_2 (v_2 hasn't been assigned a value yet) ; Round 12 is "a little" slow but is enough to demonstrate how worst things turn For $i = 1 To 12 $v[2] = _BigNum_Add(_BigNum_Sub(111, _BigNum_Div(1130, $v[1])), _BigNum_Div(3000, _BigNum_Mul($v[1], $v[0]))) ConsoleWrite(StringFormat("Round %i\nu0 = %s\nu1 = %s\nu2 = %s\n\n", $i, $v[0], $v[1], $v[2])) $v[0] = $v[1] $v[1] = $v[2] Next ConsoleWrite(@LF)