[インデックス 12855] ファイルの概要
このコミットは、Go言語の公式ドキュメントの一部である doc/code.html
内のコード例を修正し、newmath.Sqrt
関数のテストケースが確実に成功するように更新するものです。具体的には、テストの入力値と期待される出力値を変更することで、浮動小数点演算の精度に起因する潜在的なテスト失敗を防ぎ、ドキュメントの正確性を向上させています。
コミット
commit 25e02d519d205f7424fdc2a1e6926d3dee6544b4
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Tue Apr 10 01:55:51 2012 +0800
doc/code: update newmath.Sqrt test case to make sure test succeed
Fixes #3445.
R=golang-dev, rsc, mtj
CC=golang-dev
https://golang.org/cl/5975061
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/25e02d519d205f7424fdc2a1e6926d3dee6544b4
元コミット内容
doc/code: update newmath.Sqrt test case to make sure test succeed
Fixes #3445.
R=golang-dev, rsc, mtj
CC=golang-dev
https://golang.org/cl/5975061
変更の背景
この変更は、Go言語のIssue #3445 を修正するために行われました。Issue #3445は、doc/code.html
に記載されている newmath.Sqrt
関数のテストケースが、特定の環境やGoのバージョンにおいて、浮動小数点演算の精度問題により失敗する可能性があるという報告でした。
元のテストケースでは Sqrt(9)
の結果が 3
であることを期待していましたが、浮動小数点数の平方根計算は、厳密に整数値になる場合でも、内部的には浮動小数点数として扱われるため、ごくわずかな誤差が生じることがあります。この誤差が原因で、x != out
という厳密な比較が true
となり、テストが失敗する可能性がありました。
ドキュメント内のコード例は、読者がGoの機能やテストの書き方を学ぶためのものであり、環境によってテストが失敗するような不安定な例は避けるべきです。そのため、より安定して成功するテストケースに更新する必要がありました。
前提知識の解説
Go言語のテスト
Go言語には、標準ライブラリとしてテストフレームワークが組み込まれています。テストファイルは通常、テスト対象のGoファイルと同じディレクトリに _test.go
というサフィックスを付けて配置されます。テスト関数は Test
で始まり、*testing.T
型の引数を取ります。
go test
: Goのテストを実行するためのコマンドです。指定されたパッケージ内の_test.go
ファイルを見つけ、テスト関数を実行します。testing.T
: テストの実行中にエラーを報告したり、テストの進行状況を制御したりするためのメソッドを提供します。t.Errorf(...)
: テストが失敗したことを報告し、指定されたフォーマット文字列と引数でエラーメッセージを出力します。テストは続行されます。t.Fatalf(...)
: テストが失敗したことを報告し、エラーメッセージを出力した後、テストの実行を停止します。
const
: Goにおける定数宣言です。コンパイル時に値が決定され、不変です。package newmath
: この例では、newmath
という名前のパッケージが定義されており、その中にSqrt
関数が含まれていることを示唆しています。これは、Goのパッケージ構造と、関数が特定のパッケージに属するという概念を示しています。
浮動小数点演算の精度
コンピュータにおける浮動小数点数(float32
, float64
など)の表現は、有限のビット数で行われるため、すべての実数を正確に表現できるわけではありません。特に、平方根のような演算では、結果が厳密な整数値であっても、内部的にはわずかな誤差を含む浮動小数点数となることがあります。
例えば、math.Sqrt(9.0)
は 3.0
を返しますが、これは float64
型の 3.0
であり、厳密には 3
という整数値とは異なるバイナリ表現を持つ可能性があります。そのため、x == 3
のような厳密な等価比較は、予期せぬ false
を返すことがあります。このような場合、通常は許容誤差(epsilon)を設けて比較を行うか、テストケース自体を厳密な浮動小数点比較が不要なものに変更します。
技術的詳細
このコミットは、doc/code.html
ファイル内のGoコード例を修正しています。このファイルは、Goの公式ドキュメントの一部であり、Goの基本的な使い方やテストの書き方を示すためのものです。
変更の核心は、newmath.Sqrt
関数のテストケースにおける入力値と期待される出力値の変更です。
-
変更前:
func TestSqrt(t *testing.T) { const in, out = 9, 3 if x := Sqrt(in); x != out { t.Errorf("Sqrt(%v) = %v, want %v", in, x, out) } }
ここでは、
in
が9
、out
が3
と設定されていました。Sqrt(9)
の結果が厳密に3
となることを期待していましたが、前述の浮動小数点数の精度問題により、Sqrt(9)
の結果が3.0000000000000004
のような値になり、x != out
がtrue
と評価されてテストが失敗する可能性がありました。 -
変更後:
func TestSqrt(t *testing.T) { const in, out = 4, 2 if x := Sqrt(in); x != out { t.Errorf("Sqrt(%v) = %v, want %v", in, x, out) } }
変更後では、
in
が4
、out
が2
に設定されています。Sqrt(4)
の結果も浮動小数点数として2.0
に非常に近い値になりますが、9
の平方根よりも4
の平方根の方が、多くの浮動小数点表現においてより正確に2.0
として表現されやすい、あるいは誤差がテストの厳密な比較に影響を与えにくいという特性があります。この変更により、テストがより安定して成功するようになりました。
また、go test
の出力例も更新されています。
- 変更前:
$ go test example/newmath ok example/newmath
- 変更後:
これは、$ go test example/newmath ok example/newmath 0.165s
go test
コマンドがテスト実行にかかった時間(0.165s
)も出力するようになったことを反映しています。これはGoのテストツールの進化に伴うドキュメントの更新です。
コアとなるコードの変更箇所
--- a/doc/code.html
+++ b/doc/code.html
@@ -384,7 +384,7 @@ package newmath
import "testing"
func TestSqrt(t *testing.T) {
- const in, out = 9, 3
+ const in, out = 4, 2
if x := Sqrt(in); x != out {
\tt.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
}
@@ -397,7 +397,7 @@ Now run the test with <code>go test</code>:
<pre>
$ go test example/newmath
-ok example/newmath
+ok example/newmath 0.165s
</pre>
<p>
コアとなるコードの解説
上記の差分は、doc/code.html
ファイル内の2つの主要な変更を示しています。
-
テストケースの入力値と期待値の変更:
const in, out = 9, 3
がconst in, out = 4, 2
に変更されました。- これは、
TestSqrt
関数内で使用される定数in
とout
の値を更新しています。in
はSqrt
関数への入力、out
はその期待される出力です。この変更の目的は、Sqrt(9)
が浮動小数点演算の精度問題によりテストが不安定になる可能性があったため、より安定してテストが成功するSqrt(4)
のケースに変更することです。4
の平方根は2
であり、多くの浮動小数点表現でより正確に表現されやすいため、テストの信頼性が向上します。
-
go test
出力例の更新:ok example/newmath
がok example/newmath 0.165s
に変更されました。- これは、
go test
コマンドの出力形式が更新され、テスト実行にかかった時間も表示されるようになったことを反映しています。ドキュメントのコード例と実際のコマンド出力が一致するように修正されました。
これらの変更は、Goのドキュメントの正確性と、読者がコード例を試した際の体験の安定性を向上させることを目的としています。
関連リンク
- Go Issue #3445: https://github.com/golang/go/issues/3445
- Go CL 5975061: https://golang.org/cl/5975061
参考にした情報源リンク
- Go言語の公式ドキュメント (特にテストに関するセクション)
- 浮動小数点数の精度に関する一般的な情報 (IEEE 754など)
- GitHubのGoリポジトリのIssue #3445の議論内容
- Goのコードレビューシステム (Gerrit) のCL 5975061の内容