[インデックス 10695] ファイルの概要
このコミットは、Go言語の仕様書(doc/go_spec.html
)における複素数定数の例を修正するものです。具体的には、1 - 0.707
という実数定数の減算の例を、1 - 0.707i
という複素数定数の減算の例に調整し、より正確な「untyped complex constant」(型なし複素数定数)の表現を示しています。また、仕様書のバージョン日付も更新されています。
コミット
commit 1084ab98b77cc9c231a7e21257f223b49046019b
Author: Robert Hencke <robert.hencke@gmail.com>
Date: Sat Dec 10 10:04:33 2011 -0800
spec: adjust complex constant example
Fixes https://golang.org/cl/5444053/#msg41
R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/5478058
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1084ab98b77cc9c231a7e21257f223b49046019b
元コミット内容
spec: adjust complex constant example
Fixes https://golang.org/cl/5444053/#msg41
R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/5478058
変更の背景
この変更は、Go言語の仕様書における複素数定数の例が、その意図する「型なし複素数定数」を正確に表現していなかったために行われました。元の例const Σ = 1 - 0.707
は、1
も0.707
も実数リテラルであるため、結果として実数定数(0.293
)となり、複素数定数の例としては不適切でした。
コミットメッセージに記載されているFixes https://golang.org/cl/5444053/#msg41
のリンクは、この問題に関する議論を示しています。この議論では、Goの定数評価のルールにおいて、実数リテラルのみで構成された式は、たとえそれが複素数型に代入される文脈であっても、自動的に複素数定数とは見なされないことが指摘されています。複素数定数として扱われるためには、少なくとも一つの項に虚数単位i
が含まれている必要があります。
この修正は、仕様書の正確性を保ち、読者がGo言語の複素数定数の挙動を正しく理解できるようにするために必要でした。
前提知識の解説
Go言語の定数 (Constants)
Go言語における定数は、コンパイル時に値が決定される不変のエンティティです。定数は数値、真偽値、文字列のいずれかであり、型を持つことも持たないこともあります。
- 型なし定数 (Untyped Constants): Goの定数の特徴的な概念です。型なし定数は、特定のGoの型に関連付けられていません。これにより、より柔軟な型チェックが可能になります。例えば、型なしの整数定数は、
int
、int32
、int64
など、その値が収まる任意の整数型に代入できます。型なし定数は、式の中で使用される際に、そのコンテキストに応じて適切な型に「昇格」または「変換」されます。 - 型付き定数 (Typed Constants): 明示的に型が指定された定数です。例:
const PI float64 = 3.14159
。
Go言語の複素数 (Complex Numbers)
Go言語は、組み込みで複素数型をサポートしています。complex64
とcomplex128
の2つの型があります。
complex64
:float32
のペア(実部と虚部)で構成されます。complex128
:float64
のペア(実部と虚部)で構成されます。
複素数リテラルは、実数部と虚数部を組み合わせた形式で記述されます。虚数部は、数値の後に虚数単位i
を付けて表現します。例: 3.14 + 2.71i
。
虚数単位 i
数学における虚数単位 i
は、i^2 = -1
を満たす数です。Go言語では、この虚数単位をリテラルとして直接使用できます。例えば、1i
は虚数i
を表し、0.707i
は虚数0.707i
を表します。
iota
iota
はGo言語の特別な識別子で、const
宣言ブロック内で連続する定数値を生成するために使用されます。iota
はconst
ブロック内で0から始まり、新しいconst
指定ごとに1ずつ増加します。これは、列挙型のような定数セットを簡潔に定義するのに非常に便利です。
例:
const (
A = iota // A = 0
B = iota // B = 1
C = iota // C = 2
)
または、より簡潔に:
const (
A = iota // A = 0
B // B = 1
C // C = 2
)
このコミットの例では、Φ = iota*1i - 1/1i
のように、iota
が複素数定数の定義に使用されています。これは、iota
が数値定数として振る舞い、複素数リテラルと組み合わせて使用できることを示しています。
技術的詳細
このコミットの核心は、Go言語の定数評価における複素数の扱いに関する正確な記述です。
Go言語では、数値定数はその値が表現できる限り、任意の精度で扱われます。そして、その定数が使用されるコンテキスト(例えば、変数への代入や他の式の一部として)に基づいて型が決定されます。
元の仕様書の例:
const Σ = 1 - 0.707 // (untyped complex constant)
この行の問題は、1
も0.707
も実数リテラルであるため、1 - 0.707
という式は純粋な実数演算として評価され、結果は0.293
という実数定数になります。Goのコンパイラは、この式が「複素数定数」として意図されていることを自動的に推論しません。複素数定数として扱われるためには、少なくとも一つのオペランドが虚数単位i
を含む必要があります。
修正後の仕様書の例:
const Σ = 1 - 0.707i // (untyped complex constant)
この修正により、0.707i
という虚数リテラルが導入されました。1
は実数リテラル、0.707i
は虚数リテラルです。実数と虚数の減算は、結果として複素数定数になります。この場合、Σ
は実部が1
、虚部が-0.707
の型なし複素数定数となります。これにより、この例が「型なし複素数定数」を正しく示していることになります。
この変更は、Go言語の定数に関する厳密なルール、特に複素数定数の構成方法を明確にする上で重要です。Goでは、型なし定数の柔軟性がある一方で、リテラルの形式がその定数の「種類」(整数、浮動小数点数、複素数)を決定する上で重要な役割を果たします。
また、仕様書のバージョン日付がDecember 8, 2011
からDecember 10, 2011
に更新されているのは、この修正が適用された日付を反映するためです。
コアとなるコードの変更箇所
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,5 +1,5 @@
<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of December 8, 2011 -->
+<!-- subtitle Version of December 10, 2011 -->
<!--
TODO
@@ -3432,7 +3432,7 @@ const j = true // j == true (untyped boolean constant)
const k = 'w' + 1 // k == 'x' (untyped character constant)
const l = "hi" // l == "hi" (untyped string constant)
const m = string(k) // m == "x" (type string)\n-const Σ = 1 - 0.707 // (untyped complex constant)
+const Σ = 1 - 0.707i // (untyped complex constant)
const Δ = Σ + 2.0e-4 // (untyped complex constant)
const Φ = iota*1i - 1/1i // (untyped complex constant)
</pre>
コアとなるコードの解説
変更はdoc/go_spec.html
ファイル内の2箇所です。
-
仕様書の日付更新:
-<!-- subtitle Version of December 8, 2011 -->
+<!-- subtitle Version of December 10, 2011 -->
これは、仕様書の内容が更新された日付を反映するための単純な変更です。 -
複素数定数の例の修正:
-const Σ = 1 - 0.707 // (untyped complex constant)
+const Σ = 1 - 0.707i // (untyped complex constant)
この行がこのコミットの主要な変更点です。- 変更前:
1 - 0.707
は、実数リテラル同士の減算であり、結果は実数定数0.293
となります。コメントでは「untyped complex constant」とありますが、実際の値は複素数ではありませんでした。 - 変更後:
1 - 0.707i
は、実数リテラル1
と虚数リテラル0.707i
の減算です。Go言語では、実数と虚数の演算は複素数を生成します。したがって、この式の結果は実部が1
、虚部が-0.707
の「型なし複素数定数」となります。これにより、コメントとコードの整合性が取れ、Goの複素数定数の正しい記述方法が示されるようになりました。
- 変更前:
この修正により、Go言語の仕様書がより正確になり、読者が複素数定数の定義方法を誤解する可能性が低減されました。
関連リンク
- Go言語の仕様書 (Go Programming Language Specification): このコミットが修正しているドキュメントの全体像を理解するために参照すると良いでしょう。 https://go.dev/ref/spec
- Go言語のコードレビューシステム (Gerrit):
コミットメッセージに記載されている
https://golang.org/cl/5478058
は、この変更がGoのGerritコードレビューシステムでどのように議論され、承認されたかを示しています。 https://golang.org/cl/5478058 - 関連する議論 (Gerrit Message):
https://golang.org/cl/5444053/#msg41
は、この修正の背景となった具体的な議論や提案のメッセージへのリンクです。 https://golang.org/cl/5444053/#msg41
参考にした情報源リンク
- Go言語の公式ドキュメントおよび仕様書
- Go言語のGerritコードレビューシステム上の関連する変更履歴と議論
- Go言語における定数と複素数に関する一般的な知識