1 // The Computer Language Benchmarks Game
2 // http://benchmarksgame.alioth.debian.org/
4 // contributed by the Rust Project Developers
6 // Copyright (c) 2013-2014 The Rust Project Developers
8 // All rights reserved.
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions
14 // - Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
17 // - Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in
19 // the documentation and/or other materials provided with the
22 // - Neither the name of "The Computer Language Benchmarks Game" nor
23 // the name of "The Computer Language Shootout Benchmarks" nor the
24 // names of its contributors may be used to endorse or promote
25 // products derived from this software without specific prior
26 // written permission.
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 // OF THE POSSIBILITY OF SUCH DAMAGE.
43 use std::from_str::FromStr;
46 use std::num::FromPrimitive;
48 use num::bigint::BigInt;
65 fn from_int(i: int) -> BigInt {
66 FromPrimitive::from_int(i).unwrap()
69 fn extract_digit(&self) -> int {
70 if self.numer > self.accum {return -1;}
72 (self.numer * Context::from_int(3) + self.accum)
73 .div_rem(&self.denom);
74 if r + self.numer >= self.denom {return -1;}
78 fn next_term(&mut self, k: int) {
79 let y2 = Context::from_int(k * 2 + 1);
80 self.accum = (self.accum + (self.numer << 1)) * y2;
81 self.numer = self.numer * Context::from_int(k);
82 self.denom = self.denom * y2;
85 fn eliminate_digit(&mut self, d: int) {
86 let d = Context::from_int(d);
87 let ten = Context::from_int(10);
88 self.accum = (self.accum - self.denom * d) * ten;
89 self.numer = self.numer * ten;
95 let mut context = Context::new();
97 for i in range(1, n + 1) {
101 context.next_term(k);
102 d = context.extract_digit();
107 if i % 10 == 0 {print!("\t:{}\n", i);}
109 context.eliminate_digit(d);
114 for _ in range(m, 10) { print!(" "); }
115 print!("\t:{}\n", n);
120 let args = std::os::args();
121 let args = args.as_slice();
122 let n = if args.len() < 2 {
125 FromStr::from_str(args[1].as_slice()).unwrap()