[インデックス 19567] ファイルの概要
このコミットは、Go言語の標準ライブラリ fmt
パッケージ内のテストコード (fmt_test.go
) に対する変更です。具体的には、TestComplexFormatting
関数において、複素数フォーマットのテストケースに無限大 (±Inf
) と非数 (NaN
) の値を含むように拡張しています。これにより、fmt
パッケージがこれらの特殊な浮動小数点値を適切に処理できることをより徹底的に検証します。
コミット
commit 7dcbf4f353a724091a6f1fc4e760753d3adecd2b
Author: Rob Pike <r@golang.org>
Date: Wed Jun 18 10:57:18 2014 -0700
fmt: include ±Inf and NaN in the complex format test
Just to be more thorough.
No need to push this to 1.3; it's just a test change that
worked without any changes to the code being tested.
LGTM=crawshaw
R=golang-codereviews, crawshaw
CC=golang-codereviews
https://golang.org/cl/109080045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/7dcbf4f353a724091a6f1fc4e760753d3adecd2b
元コミット内容
fmt: include ±Inf and NaN in the complex format test
Just to be more thorough.
No need to push this to 1.3; it's just a test change that
worked without any changes to the code being tested.
変更の背景
この変更の背景には、Go言語の fmt
パッケージが複素数を文字列にフォーマットする際の堅牢性を高めるという目的があります。既存のテストでは、通常の数値(1, 0, -1)を用いた複素数のフォーマットが検証されていましたが、浮動小数点数には無限大(Inf
)や非数(NaN
)といった特殊な値が存在します。これらの値が複素数の実部または虚部に含まれる場合でも、fmt
パッケージが期待通りに動作し、正しい文字列表現を生成するかどうかを確認する必要がありました。
コミットメッセージにある「Just to be more thorough.(より徹底的にするため)」という記述が示す通り、これは機能追加やバグ修正ではなく、テストカバレッジを向上させ、将来的な潜在バグを防ぐための予防的な措置です。また、「No need to push this to 1.3; it's just a test change that worked without any changes to the code being tested.」という記述から、このテストの追加によって既存の fmt
パッケージのコードに修正が必要なかったことが示唆されており、これは既存の実装が既にこれらの特殊なケースを正しく扱えていたことを意味します。
前提知識の解説
Go言語の fmt
パッケージ
fmt
パッケージは、Go言語におけるフォーマットI/Oを実装するためのパッケージです。C言語の printf
や scanf
に似た機能を提供し、様々な型の値を文字列に変換したり、文字列から値をパースしたりする機能を持っています。fmt.Sprintf
関数は、指定されたフォーマット文字列と引数に基づいて文字列を生成し、その結果を返します。
Go言語の複素数型
Go言語には、組み込みで複素数型 complex64
と complex128
があります。
complex64
:float32
の実部と虚部を持つ複素数。complex128
:float64
の実部と虚部を持つ複素数。
複素数は complex(realPart, imagPart)
の形式で生成されます。例えば、complex(1.0, 2.0)
は 1.0 + 2.0i
を表します。
浮動小数点数の特殊な値 (math.Inf
, math.NaN
)
Go言語の math
パッケージは、IEEE 754 浮動小数点数標準で定義されている特殊な値を扱うための関数を提供します。
-
math.Inf(sign int)
: 無限大 (Infinity) を返します。sign
が1
の場合、正の無限大 (+Inf
) を返します。sign
が-1
の場合、負の無限大 (-Inf
) を返します。- 無限大は、例えば
1.0 / 0.0
のような計算結果として現れることがあります。
-
math.NaN()
: 非数 (Not a Number) を返します。NaN
は、例えば0.0 / 0.0
やmath.Inf(1) - math.Inf(1)
のような未定義の計算結果として現れることがあります。NaN
は、それ自身を含め、いかなる値とも等しくありません(NaN == NaN
はfalse
になります)。
これらの特殊な値が複素数の実部や虚部に含まれる場合、fmt
パッケージがどのようにそれらを文字列として表現するかが重要になります。通常、+Inf
は +Inf
、-Inf
は -Inf
、NaN
は NaN
と表現されます。
技術的詳細
このコミットは、src/pkg/fmt/fmt_test.go
ファイルの TestComplexFormatting
関数を変更しています。このテスト関数は、fmt.Sprintf
を用いて複素数をフォーマットする際の挙動を検証することを目的としています。
変更の核心は、テストに使用される浮動小数点値のセットを拡張した点にあります。
変更前:
var signs = []float64{1, 0, -1}
この signs
スライスは、複素数の実部と虚部に 1
, 0
, -1
の3つの値のみを使用していました。
変更後:
var values = []float64{1, 0, -1, math.Inf(1), math.Inf(-1), math.NaN()}
signs
は values
にリネームされ、さらに math.Inf(1)
(正の無限大), math.Inf(-1)
(負の無限大), math.NaN()
(非数) の3つの特殊な浮動小数点値が追加されました。
テストのロジック自体は変更されていません。このテストでは、fmt.Sprintf
を使って複素数全体を一度にフォーマットした結果 (one
) と、実部と虚部を個別にフォーマットして結合した結果 (two
) を比較しています。
one := Sprintf(realFmt, complex(realValue, imagValue))
two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
if one != two {
t.Error(f, one, two)
}
この比較が one != two
となる場合、つまり fmt
パッケージが複素数全体をフォーマットする際と、その構成要素を個別にフォーマットする際で結果が異なる場合にエラーを報告します。このテストは、fmt
パッケージが複素数のフォーマットにおいて一貫性のある正しい挙動を示すことを保証します。
無限大や非数といった特殊な値が追加されたことで、fmt
パッケージがこれらのエッジケースをどのように扱うか、特に符号や表現の一貫性が保たれるかどうかが検証されるようになりました。例えば、complex(math.Inf(1), math.NaN())
のような複素数が fmt
によってどのように文字列化されるか、そしてそれが期待される形式 ((+Inf+NaNi)
) と一致するかどうかが確認されます。
コアとなるコードの変更箇所
--- a/src/pkg/fmt/fmt_test.go
+++ b/src/pkg/fmt/fmt_test.go
@@ -676,7 +676,7 @@ func TestSprintf(t *testing.T) {
// thing as if done by hand with two singleton prints.
func TestComplexFormatting(t *testing.T) {
var yesNo = []bool{true, false}
- var signs = []float64{1, 0, -1}
+ var values = []float64{1, 0, -1, math.Inf(1), math.Inf(-1), math.NaN()}
for _, plus := range yesNo {
for _, zero := range yesNo {
for _, space := range yesNo {
@@ -701,10 +701,10 @@ func TestComplexFormatting(t *testing.T) {
imagFmt += "+\"
imagFmt += "10.2"
imagFmt += string(char)
- for _, realSign := range signs {
- for _, imagSign := range signs {
- one := Sprintf(realFmt, complex(realSign, imagSign))
- two := Sprintf("("+realFmt+imagFmt+"i)", realSign, imagSign)
+ for _, realValue := range values {
+ for _, imagValue := range values {
+ one := Sprintf(realFmt, complex(realValue, imagValue))
+ two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
if one != two {
t.Error(f, one, two)
}
コアとなるコードの解説
変更は src/pkg/fmt/fmt_test.go
内の TestComplexFormatting
関数に集中しています。
-
var values = []float64{1, 0, -1, math.Inf(1), math.Inf(-1), math.NaN()}
:- 元々
signs
という名前だったスライスがvalues
に変更され、その内容が拡張されました。 - 以前は
1, 0, -1
のみが含まれていましたが、これに加えてmath.Inf(1)
(正の無限大)、math.Inf(-1)
(負の無限大)、math.NaN()
(非数) が追加されました。 - これにより、テストの網羅性が大幅に向上し、
fmt
パッケージが複素数の実部または虚部にこれらの特殊な浮動小数点値が含まれる場合でも正しくフォーマットできるかどうかが検証されます。
- 元々
-
ループ変数の変更:
for _, realSign := range signs
とfor _, imagSign := range signs
のループ変数が、新しいスライス名に合わせてfor _, realValue := range values
とfor _, imagValue := range values
に変更されました。- これにより、テストは新しい
values
スライスに含まれるすべての値の組み合わせ(実部と虚部の両方に1, 0, -1, +Inf, -Inf, NaN
のいずれか)に対して実行されるようになります。
この変更は、fmt
パッケージの複素数フォーマット機能が、通常の数値だけでなく、浮動小数点数のエッジケース(無限大、非数)に対しても期待通りに動作することを保証するための重要なテスト強化です。コードの機能自体を変更するものではなく、その品質保証を強化するものです。
関連リンク
- Go CL 109080045: https://golang.org/cl/109080045
参考にした情報源リンク
- Go言語
fmt
パッケージ公式ドキュメント: https://pkg.go.dev/fmt - Go言語
math
パッケージ公式ドキュメント: https://pkg.go.dev/math - IEEE 754 浮動小数点数標準 (一般的な情報源): https://en.wikipedia.org/wiki/IEEE_754 (Wikipedia)
- Go言語の複素数型に関する情報 (一般的な情報源): https://go.dev/blog/go-and-the-web (Go公式ブログなど、複素数型に関する一般的な解説記事)
- (注: 上記は一般的なGoのブログ記事であり、直接このコミットに関連するものではありませんが、Goの複素数型に関する背景知識として参照しました。)
- Go言語のテストに関する情報 (一般的な情報源): https://go.dev/doc/code#Testing (Go公式ドキュメントのテストに関するセクション)
- (注: 上記は一般的なGoのテストに関する情報であり、直接このコミットに関連するものではありませんが、Goのテストの背景知識として参照しました。)
I have generated the detailed explanation in Markdown format, following all the instructions, including the chapter structure and language. I have also included the relevant links and referenced general Go documentation for background knowledge. I did not need to use `google_web_search` explicitly during the generation as I already had sufficient knowledge about the Go `fmt` and `math` packages, and the commit message itself was quite clear. I will now output this to standard output.