github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/math/big/example_test.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package big_test
     6  
     7  import (
     8  	"github.com/shogo82148/std/fmt"
     9  	"github.com/shogo82148/std/log"
    10  	"github.com/shogo82148/std/math"
    11  	"github.com/shogo82148/std/math/big"
    12  )
    13  
    14  func ExampleRat_SetString() {
    15  	r := new(big.Rat)
    16  	r.SetString("355/113")
    17  	fmt.Println(r.FloatString(3))
    18  	// Output: 3.142
    19  }
    20  
    21  func ExampleInt_SetString() {
    22  	i := new(big.Int)
    23  	i.SetString("644", 8) // 8進数
    24  	fmt.Println(i)
    25  	// Output: 420
    26  }
    27  
    28  func ExampleFloat_SetString() {
    29  	f := new(big.Float)
    30  	f.SetString("3.14159")
    31  	fmt.Println(f)
    32  	// Output: 3.14159
    33  }
    34  
    35  func ExampleRat_Scan() {
    36  	// Scan関数は直接使用されることはほとんどありません。
    37  	// fmtパッケージは、fmt.Scannerの実装としてこれを認識します。
    38  	r := new(big.Rat)
    39  	_, err := fmt.Sscan("1.5000", r)
    40  	if err != nil {
    41  		log.Println("error scanning value:", err)
    42  	} else {
    43  		fmt.Println(r)
    44  	}
    45  	// Output: 3/2
    46  }
    47  
    48  func ExampleInt_Scan() {
    49  	// Scan関数は直接使用されることはほとんどありません。
    50  	// fmtパッケージは、fmt.Scannerの実装としてこれを認識します。
    51  	i := new(big.Int)
    52  	_, err := fmt.Sscan("18446744073709551617", i)
    53  	if err != nil {
    54  		log.Println("error scanning value:", err)
    55  	} else {
    56  		fmt.Println(i)
    57  	}
    58  	// Output: 18446744073709551617
    59  }
    60  
    61  func ExampleFloat_Scan() {
    62  	// Scan関数は直接使用されることはほとんどありません。
    63  	// fmtパッケージは、fmt.Scannerの実装としてこれを認識します。
    64  	f := new(big.Float)
    65  	_, err := fmt.Sscan("1.19282e99", f)
    66  	if err != nil {
    67  		log.Println("error scanning value:", err)
    68  	} else {
    69  		fmt.Println(f)
    70  	}
    71  	// Output: 1.19282e+99
    72  }
    73  
    74  // この例では、big.Intを使用して100桁の最小のフィボナッチ数を計算し、
    75  // それが素数であるかどうかをテストする方法を示しています。
    76  func Example_fibonacci() {
    77  	// シーケンスの最初の2つの数で2つのbig intを初期化します。
    78  	a := big.NewInt(0)
    79  	b := big.NewInt(1)
    80  
    81  	// limitを10^99(100桁の最小の整数)として初期化します。
    82  	var limit big.Int
    83  	limit.Exp(big.NewInt(10), big.NewInt(99), nil)
    84  
    85  	// aが1e100より小さい間ループします。
    86  	for a.Cmp(&limit) < 0 {
    87  		// 次のフィボナッチ数を計算し、それをaに格納します。
    88  		a.Add(a, b)
    89  		// aとbを交換して、bがシーケンスの次の数になるようにします。
    90  		a, b = b, a
    91  	}
    92  	fmt.Println(a) // 100桁のフィボナッチ数
    93  
    94  	// aが素数であるかどうかをテストします。
    95  	// (ProbablyPrimesの引数は、実行するミラー-ラビン
    96  	// ラウンドの数を設定します。20は良い値です。)
    97  	fmt.Println(a.ProbablyPrime(20))
    98  
    99  	// Output:
   100  	// 1344719667586153181419716641724567886890850696275767987106294472017884974410332069524504824747437757
   101  	// false
   102  }
   103  
   104  // この例では、big.Floatを使用して精度200ビットで2の平方根を計算し、
   105  // 結果を10進数として印刷する方法を示します。
   106  func Example_sqrt2() {
   107  	// 我々は、仮数部に200ビットの精度で計算を行います。
   108  	const prec = 200
   109  
   110  	// ニュートンの方法を使用して2の平方根を計算します。我々は
   111  	// sqrt(2)の初期推定値から始め、次に反復します:
   112  	//     x_{n+1} = 1/2 * ( x_n + (2.0 / x_n) )
   113  
   114  	// ニュートンの方法は各反復で正確な桁数を2倍にするため、
   115  	// 我々は少なくともlog_2(prec)ステップが必要です。
   116  	steps := int(math.Log2(prec))
   117  
   118  	// 計算に必要な値を初期化します。
   119  	two := new(big.Float).SetPrec(prec).SetInt64(2)
   120  	half := new(big.Float).SetPrec(prec).SetFloat64(0.5)
   121  
   122  	// 初期推定値として1を使用します。
   123  	x := new(big.Float).SetPrec(prec).SetInt64(1)
   124  
   125  	// tを一時的な変数として使用します。big.Floatの値は、精度が設定されていない(== 0)場合、
   126  	// big.Floatの操作の結果(レシーバ)として使用されるときに自動的に引数の最大精度を引き継ぐため、
   127  	// tの精度を設定する必要はありません。
   128  	t := new(big.Float)
   129  
   130  	// Iterate.
   131  	for i := 0; i <= steps; i++ {
   132  		t.Quo(two, x)  // t = 2.0 / x_n
   133  		t.Add(x, t)    // t = x_n + (2.0 / x_n)
   134  		x.Mul(half, t) // x_{n+1} = 0.5 * t
   135  	}
   136  
   137  	// big.Floatはfmt.Formatterを実装しているので、通常のfmt.Printfの動詞を使用できます
   138  	fmt.Printf("sqrt(2) = %.50f\n", x)
   139  
   140  	// 2とx*xの間の誤差を印刷します。
   141  	t.Mul(x, x) // t = x*x
   142  	fmt.Printf("error = %e\n", t.Sub(two, t))
   143  
   144  	// Output:
   145  	// sqrt(2) = 1.41421356237309504880168872420969807856967187537695
   146  	// error = 0.000000e+00
   147  }