The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

hanafey (18) [Avatar] Offline
#1
Listing 1.1 has a nasty surprise if you don't like the fact that the golden ratio is only computed to a precision of 1.0e-9, and so you make a seeming reasonable change and make the convergence test 1.0e-15. (Not understanding how groovy is treating untyped numbers you make the assumption that at least IEEE double precision would be available. The Java programmer thinks integer division might be a problem, but clearly decimal numbers are getting computed...)

The surprise is the algorithm no longer terminates.

The example is almost Python syntax, so with a few tweaks you can run it as Python, and Python dutifully computes a more accurate golden ratio with only a few more iterations.

So you make "fibo" start with "[1.0, 1.0]" but strangely this does not fix the problem (and it is not because float precision is being used). So you set "fibo" to "[1.0d, 1.0d]" and now it works. But "[1.0f, 1.0f]" also works because computations are always double precision.

Given that the example is numerical in nature it seems that the example should use doubles -- the reader should learn early that 1.0 is not going to behave like 1.0d as it would in Java (and maybe the book will reveal why this is a good design decision in groovy, although it escapes me at the moment).
paulk_asert (33) [Avatar] Offline
#2
Re: Precision of numerical operations
Groovy uses BigDecimal for division (unless intdiv is used). The default precision for BigDecimal is 10. You can use another precision but you lose some of Groovy's syntactic sugar since at the moment you have to explicitly use a MathContext (there is an unresolved Jira requesting the ability to make the default user configurable). You could for example use "mc = MathContext.DECIMAL64" which has 16 as the precision. Then instead of "fibo[-1] + fibo[-2]" you need to use "fibo[-1].add(fibo[-2], mc)". This would let you alter the convergence test to use 1.0e-15. When I tested this I seeded fibo with BigDecimals created using the same mc context.