Russ Cox | c3f4319 | 2012-03-06 23:27:30 -0500 | [diff] [blame] | 1 | // +build ignore |
| 2 | |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 3 | /* |
| 4 | Redistribution and use in source and binary forms, with or without |
| 5 | modification, are permitted provided that the following conditions are met: |
| 6 | |
| 7 | * Redistributions of source code must retain the above copyright |
| 8 | notice, this list of conditions and the following disclaimer. |
| 9 | |
| 10 | * Redistributions in binary form must reproduce the above copyright |
| 11 | notice, this list of conditions and the following disclaimer in the |
| 12 | documentation and/or other materials provided with the distribution. |
| 13 | |
| 14 | * Neither the name of "The Computer Language Benchmarks Game" nor the |
| 15 | name of "The Computer Language Shootout Benchmarks" nor the names of |
| 16 | its contributors may be used to endorse or promote products derived |
| 17 | from this software without specific prior written permission. |
| 18 | |
| 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 23 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 24 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 25 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 27 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 28 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 29 | POSSIBILITY OF SUCH DAMAGE. |
| 30 | */ |
| 31 | |
| 32 | /* The Computer Language Benchmarks Game |
| 33 | * http://shootout.alioth.debian.org/ |
| 34 | * |
| 35 | * contributed by The Go Authors. |
| 36 | * based on pidigits.c (by Paolo Bonzini & Sean Bartlett, |
| 37 | * modified by Michael Mellor) |
| 38 | */ |
| 39 | |
| 40 | package main |
| 41 | |
| 42 | import ( |
Russ Cox | c3f4319 | 2012-03-06 23:27:30 -0500 | [diff] [blame] | 43 | big "." |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 44 | "fmt" |
| 45 | "runtime" |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 46 | ) |
| 47 | |
| 48 | var ( |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 49 | tmp1 = big.NewInt(0) |
| 50 | tmp2 = big.NewInt(0) |
| 51 | numer = big.NewInt(1) |
| 52 | accum = big.NewInt(0) |
| 53 | denom = big.NewInt(1) |
| 54 | ten = big.NewInt(10) |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 55 | ) |
| 56 | |
| 57 | func extractDigit() int64 { |
| 58 | if big.CmpInt(numer, accum) > 0 { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 59 | return -1 |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 60 | } |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 61 | tmp1.Lsh(numer, 1).Add(tmp1, numer).Add(tmp1, accum) |
| 62 | big.DivModInt(tmp1, tmp2, tmp1, denom) |
| 63 | tmp2.Add(tmp2, numer) |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 64 | if big.CmpInt(tmp2, denom) >= 0 { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 65 | return -1 |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 66 | } |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 67 | return tmp1.Int64() |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | func nextTerm(k int64) { |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 71 | y2 := k*2 + 1 |
| 72 | accum.Add(accum, tmp1.Lsh(numer, 1)) |
| 73 | accum.Mul(accum, tmp1.SetInt64(y2)) |
| 74 | numer.Mul(numer, tmp1.SetInt64(k)) |
| 75 | denom.Mul(denom, tmp1.SetInt64(y2)) |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | func eliminateDigit(d int64) { |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 79 | accum.Sub(accum, tmp1.Mul(denom, tmp1.SetInt64(d))) |
| 80 | accum.Mul(accum, ten) |
| 81 | numer.Mul(numer, ten) |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | func main() { |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 85 | i := 0 |
| 86 | k := int64(0) |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 87 | for { |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 88 | d := int64(-1) |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 89 | for d < 0 { |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 90 | k++ |
| 91 | nextTerm(k) |
| 92 | d = extractDigit() |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 93 | } |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 94 | eliminateDigit(d) |
| 95 | fmt.Printf("%c", d+'0') |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 96 | |
| 97 | if i++; i%50 == 0 { |
Robert Griesemer | 5a1d332 | 2009-12-15 15:33:31 -0800 | [diff] [blame] | 98 | fmt.Printf("\n") |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 99 | if i >= 1000 { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 100 | break |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 101 | } |
| 102 | } |
| 103 | } |
| 104 | |
Shenghou Ma | 1abd8d8 | 2012-03-21 00:51:48 +0800 | [diff] [blame] | 105 | fmt.Printf("\n%d calls; bit sizes: %d %d %d\n", runtime.NumCgoCall(), numer.Len(), accum.Len(), denom.Len()) |
Russ Cox | cce0111 | 2009-09-30 11:51:08 -0700 | [diff] [blame] | 106 | } |