[go] math/big: Add small complete example of big.Float usage

712 views
Skip to first unread message

Alberto Donizetti (Gerrit)

unread,
Jun 18, 2015, 11:24:27 AM6/18/15
to Ian Lance Taylor, golang-co...@googlegroups.com
Alberto Donizetti uploaded a change:
https://go-review.googlesource.com/11245

math/big: Add small complete example of big.Float usage

Updates #11241

Change-Id: I573be85d0cfcf410f6125ecd2be8a3d292c40bbb
---
M src/math/big/example_test.go
1 file changed, 45 insertions(+), 0 deletions(-)



diff --git a/src/math/big/example_test.go b/src/math/big/example_test.go
index 37b1bd0..4fa4fa4 100644
--- a/src/math/big/example_test.go
+++ b/src/math/big/example_test.go
@@ -7,6 +7,7 @@
import (
"fmt"
"log"
+ "math"
"math/big"
)

@@ -83,3 +84,47 @@
//
1344719667586153181419716641724567886890850696275767987106294472017884974410332069524504824747437757
// false
}
+
+// Example_sqrt2 shows how to use big.Float to compute the square root of
2 with
+// a precision of 200 binary digits, and print it as a decimal number.
+func Example_sqrt2() {
+ // we'll do computations with 200 binary digits of precision in the
mantissa
+ prec := uint(200)
+
+ // Compute the square root of 2 using Newton's Method. We start with
+ // an initial guess for sqrt(2), and then iterate:
+ // x_{n+1} = 1/2 * ( x_n + (2.0 / x_n) )
+
+ // we need at least log_2(prec) iterations
+ steps := math.Log2(float64(prec))
+
+ // initialize Floats with precision prec from int64 and float64 values
+ two := new(big.Float).SetPrec(prec).SetInt64(2)
+ half := new(big.Float).SetPrec(prec).SetFloat64(0.5)
+
+ // use 1 as the initial estimate
+ x := new(big.Float).SetPrec(prec).SetInt64(1)
+
+ t := new(big.Float)
+
+ // Newton's Method iterations
+ for i := 0; i <= int(steps); i++ {
+ t.Quo(two, x) // t = 2.0 / x_n
+ t.Add(x, t) // t = x_n + (2.0 / x_n)
+ x.Mul(half, t) // x_{n+1} = 0.5 * t
+ }
+
+ // Use Text to convert the Float to a String and print it.
+ // 'f' formats the Float as a decimal number, no exponent.
+ // The precision parameter controls the number of digits after the
decimal point.
+ // 200 binary digits of mantissa are enough to give us at least 50
correct decimal digits.
+ fmt.Println(x.Text('f', 50))
+
+ // verify that x * x = 2
+ z := new(big.Float).Mul(x, x)
+ fmt.Println(two.Cmp(z) == 0)
+
+ // Output:
+ // 1.41421356237309504880168872420969807856967187537695
+ // true
+}

--
https://go-review.googlesource.com/11245

Robert Griesemer (Gerrit)

unread,
Jun 18, 2015, 12:52:12 PM6/18/15
to Alberto Donizetti, Josh Bleecher Snyder, Robert Griesemer, golang-co...@googlegroups.com
Robert Griesemer has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 1:

(4 comments)

some initial feedback

https://go-review.googlesource.com/#/c/11245/1/src/math/big/example_test.go
File src/math/big/example_test.go:

PS1, Line 92: prec
const prec = 200

and you don't need the prec conversion below


PS1, Line 99: float64
no need for float64 conversion


PS1, Line 111: steps
Possibly less efficient, but how about changing the loop so it stops
automatically once enough precision is reached? That would make this
example more useful as a template for other functions that just sqrt.


PS1, Line 121: Text
simpler:

fmt.Printf("sqrt(2) = %.50f\n", x)

big.Floats support fmt.Formatter (but the 'g' format needs a precision for
now)


--
https://go-review.googlesource.com/11245
Gerrit-Reviewer: Josh Bleecher Snyder <josh...@gmail.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-HasComments: Yes

Alberto Donizetti (Gerrit)

unread,
Jun 18, 2015, 1:30:05 PM6/18/15
to Andrew Gerrand, Josh Bleecher Snyder, Robert Griesemer, golang-co...@googlegroups.com
Alberto Donizetti has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 1:

(1 comment)

https://go-review.googlesource.com/#/c/11245/1/src/math/big/example_test.go
File src/math/big/example_test.go:

PS1, Line 111: steps
> Possibly less efficient, but how about changing the loop so it stops
> autom
Just to be sure: are you suggesting to remove the steps variable and change
the condition to

new(big.Float).Mul(x, x).Cmp(two) != 0

?


--
https://go-review.googlesource.com/11245
Gerrit-Reviewer: Alberto Donizetti <alb.do...@gmail.com>
Gerrit-Reviewer: Andrew Gerrand <a...@golang.org>

Robert Griesemer (Gerrit)

unread,
Jun 18, 2015, 1:57:43 PM6/18/15
to Alberto Donizetti, Andrew Gerrand, Josh Bleecher Snyder, Robert Griesemer, golang-co...@googlegroups.com
Robert Griesemer has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 1:

(7 comments)

https://go-review.googlesource.com/#/c/11245/1/src/math/big/example_test.go
File src/math/big/example_test.go:

PS1, Line 88: Example_sqrt2
Please see https://go-review.googlesource.com/#/c/11231/ for the style of
comments. Andrew made the example quite a bit nicer.


PS1, Line 99: float64
> no need for float64 conversion
Also, convert to int here rather than each time in the iteration below:

steps := int(math.Log2(prec))


PS1, Line 101: from
This comment is misleading: the values 2 and 0.5 are untyped (not int64 and
float64). Better to explain what you are initializing.


PS1, Line 108: big
Should explain that we don't need to set the precision for t; it is taken
from the argument's precision if it's not set.


PS1, Line 111: steps
> Just to be sure: are you suggesting to remove the steps variable and
> change
yes, I was. But in retrospect, as is is fine. Instead, explain where you
compute the steps that Newton's Method doubles precision in each iteration,
hence the Log2.


PS1, Line 121: Text
> simpler:
Also, in this case you don't need to explain the format in so much detail
anymore.


PS1, Line 123: that
I suspect for some numbers, steps iterations could lead to a result that
has an error within prec bits. Instead of just printing true/false, how
about printing the error? That's also more in the spirit of floating-point
operations (usually, float comparisons for equality should be avoided).
E.g.,

fmt.Printf("error = %e\n", t.Sub(two, z))

Alberto Donizetti (Gerrit)

unread,
Jun 18, 2015, 2:47:17 PM6/18/15
to Robert Griesemer, Andrew Gerrand, Josh Bleecher Snyder, golang-co...@googlegroups.com
Alberto Donizetti uploaded a new patch set:
https://go-review.googlesource.com/11245

math/big: Add small complete example of big.Float usage

Updates #11241

Change-Id: I573be85d0cfcf410f6125ecd2be8a3d292c40bbb
---
M src/math/big/example_test.go
1 file changed, 47 insertions(+), 0 deletions(-)

Alberto Donizetti (Gerrit)

unread,
Jun 18, 2015, 2:48:01 PM6/18/15
to Andrew Gerrand, Josh Bleecher Snyder, Robert Griesemer, golang-co...@googlegroups.com
Alberto Donizetti has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 1:

(8 comments)

https://go-review.googlesource.com/#/c/11245/1/src/math/big/example_test.go
File src/math/big/example_test.go:

PS1, Line 88: Example_sqrt2
> Please see https://go-review.googlesource.com/#/c/11231/ for the style of
> c
Done


PS1, Line 92: prec
> const prec = 200
Done


PS1, Line 99: float64
> Also, convert to int here rather than each time in the iteration below:
Done


PS1, Line 101: from
> This comment is misleading: the values 2 and 0.5 are untyped (not int64
> and
Done


PS1, Line 108: big
> Should explain that we don't need to set the precision for t; it is taken
> f
Done


PS1, Line 111: steps
> yes, I was. But in retrospect, as is is fine. Instead, explain where you
> co
Done


PS1, Line 121: Text
> Also, in this case you don't need to explain the format in so much detail
> a
Done


PS1, Line 123: that
> I suspect for some numbers, steps iterations could lead to a result that
> ha
Done


--
https://go-review.googlesource.com/11245
Gerrit-Reviewer: Alberto Donizetti <alb.do...@gmail.com>
Gerrit-Reviewer: Andrew Gerrand <a...@golang.org>
Gerrit-Reviewer: Josh Bleecher Snyder <josh...@gmail.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-HasComments: Yes

Robert Griesemer (Gerrit)

unread,
Jun 18, 2015, 4:50:11 PM6/18/15
to Alberto Donizetti, Andrew Gerrand, Josh Bleecher Snyder, Robert Griesemer, golang-co...@googlegroups.com
Robert Griesemer has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 2:

(11 comments)

a few more

https://go-review.googlesource.com/#/c/11245/2/src/math/big/example_test.go
File src/math/big/example_test.go:

PS2, Line 89: and
...and how to print...


PS2, Line 89: binary digits
s/binary digits/bits/

that's the meaning of bits


PS2, Line 91: binary digits
s/binary digits/bits/


PS2, Line 95: guess
s/guess/estimate/

like below


Line 102: // Initialize a couple of big floats we'll need during the
computation.
// Initialize values we need for the computation.


Line 111: // the argument's precision when a method is called on it.
We use t as a temporary variable. There's no need to set its precision
since big.Float values with unset (== 0) precision automatically assume the
largest precision of the arguments when used as the result (receiver) of a
big.Float operation.


PS2, Line 114: Method
// Iterate.

(Newton's Method iterations sounds odd)


Line 122: // big.Floats support fmt.Formatter.
// We can use the usual fmt.Printf verbs since big.Float implements
fmt.Formatter.


PS2, Line 125:
Print the error between 2 and x*x.

(there's no verification going on in the program)


Line 126: z := new(big.Float).Mul(x, x)
t .Mul(x, x) // t = x*x


Line 127: fmt.Printf("error = %e\n", t.Sub(two, z))
t.Sub(two, t)

Alberto Donizetti (Gerrit)

unread,
Jun 18, 2015, 5:06:48 PM6/18/15
to Robert Griesemer, Andrew Gerrand, Josh Bleecher Snyder, golang-co...@googlegroups.com
Alberto Donizetti uploaded a new patch set:
https://go-review.googlesource.com/11245

math/big: Add small complete example of big.Float usage

Updates #11241

Change-Id: I573be85d0cfcf410f6125ecd2be8a3d292c40bbb
---
M src/math/big/example_test.go
1 file changed, 47 insertions(+), 0 deletions(-)

Robert Griesemer (Gerrit)

unread,
Jun 18, 2015, 5:08:37 PM6/18/15
to Alberto Donizetti, Andrew Gerrand, Josh Bleecher Snyder, Robert Griesemer, golang-co...@googlegroups.com
Robert Griesemer has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 3: Code-Review+2

Thanks for bearing with me! Looks good.

--
https://go-review.googlesource.com/11245
Gerrit-Reviewer: Alberto Donizetti <alb.do...@gmail.com>
Gerrit-Reviewer: Andrew Gerrand <a...@golang.org>
Gerrit-Reviewer: Josh Bleecher Snyder <josh...@gmail.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-HasComments: No

Robert Griesemer (Gerrit)

unread,
Jun 18, 2015, 5:08:45 PM6/18/15
to Alberto Donizetti, Robert Griesemer, golang-...@googlegroups.com, Andrew Gerrand, Josh Bleecher Snyder, golang-co...@googlegroups.com
Robert Griesemer has submitted this change and it was merged.

math/big: Add small complete example of big.Float usage

Updates #11241

Change-Id: I573be85d0cfcf410f6125ecd2be8a3d292c40bbb
Reviewed-on: https://go-review.googlesource.com/11245
Reviewed-by: Robert Griesemer <g...@golang.org>
---
M src/math/big/example_test.go
1 file changed, 47 insertions(+), 0 deletions(-)

Approvals:
Robert Griesemer: Looks good to me, approved

Rob Pike (Gerrit)

unread,
Jun 18, 2015, 5:46:39 PM6/18/15
to Alberto Donizetti, Robert Griesemer, Andrew Gerrand, Josh Bleecher Snyder, Rob Pike, golang-co...@googlegroups.com
Rob Pike has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 4:

(1 comment)

https://go-review.googlesource.com/#/c/11245/4/src/math/big/example_test.go
File src/math/big/example_test.go:

PS4, Line 107: (
this is an easy starting point but a much smarter and more interesting one
is to halve the exponent. this is easy using MantExp


--
https://go-review.googlesource.com/11245
Gerrit-Reviewer: Alberto Donizetti <alb.do...@gmail.com>
Gerrit-Reviewer: Andrew Gerrand <a...@golang.org>
Gerrit-Reviewer: Josh Bleecher Snyder <josh...@gmail.com>
Gerrit-Reviewer: Rob Pike <r...@golang.org>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-HasComments: Yes

Alberto Donizetti (Gerrit)

unread,
Jun 18, 2015, 6:30:38 PM6/18/15
to Robert Griesemer, Andrew Gerrand, Josh Bleecher Snyder, Rob Pike, golang-co...@googlegroups.com
Alberto Donizetti has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 4:

(1 comment)

https://go-review.googlesource.com/#/c/11245/4/src/math/big/example_test.go
File src/math/big/example_test.go:

PS4, Line 107: (
> this is an easy starting point but a much smarter and more interesting one
I agree and the first version I wrote showed exactly that trick. I changed
it because in this case halving the exponent yield exactly 1 (2 is 0.5 x
2^2 => 0.5 x 2^1 which is the way big.Float will store 1) so I felt just
using 1 was simpler and a way to avoid explaining the half-exponent trick.
On the other hand taking the root of another n > 2 and using that trick
could be a nice way to show how to use MantExp.

Rob Pike (Gerrit)

unread,
Jun 18, 2015, 6:35:34 PM6/18/15
to Alberto Donizetti, Robert Griesemer, Andrew Gerrand, Josh Bleecher Snyder, Rob Pike, golang-co...@googlegroups.com
Rob Pike has posted comments on this change.

math/big: Add small complete example of big.Float usage

Patch Set 4:

(1 comment)

https://go-review.googlesource.com/#/c/11245/4/src/math/big/example_test.go
File src/math/big/example_test.go:

PS4, Line 107: (
> I agree and the first version I wrote showed exactly that trick. I changed
Compute the square root of a number larger than 2.
Reply all
Reply to author
Forward
0 new messages