Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 14432] ファイルの概要

このコミットは、Go言語の公式仕様書 doc/go_spec.html における定数式の例を修正し、Go言語における定数評価、特に整数除算と浮動小数点除算の挙動に関する記述を明確にするものです。

コミット

commit 2ae61d557aec846b9b7970022aaa0c28f17546de
Author: Robert Griesemer <gri@golang.org>
Date:   Sat Nov 17 11:16:07 2012 -0800

    spec: fix constant expression example
    
    Fixes #4400.
    
    R=r, mirtchovski
    CC=golang-dev
    https://golang.org/cl/6782084

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/2ae61d557aec846b9b7970022aaa0c28f17546de

元コミット内容

Go言語の仕様書 doc/go_spec.html の以下の箇所が変更されました。

  1. 仕様書のバージョン日付が「November 1, 2012」から「November 17, 2012」に更新されました。
  2. 定数式の例において、const Θ float64 = 3/2 のコメントが // Θ == 1.5 (type float64) から // Θ == 1.0 (type float64, 3/2 is integer division) に修正されました。
  3. 新たに const Π float64 = 3/2. // Π == 1.5 (type float64, 3/2. is float division) という例が追加されました。

変更の背景

このコミットの背景には、Go言語の定数評価における整数除算と浮動小数点除算の挙動に関する誤解や混乱があったと考えられます。特に、型を持たない定数(untyped constants)がどのように評価され、型付けされた変数に代入される際にどのような型変換が行われるかについて、仕様書の記述が不正確であったため、それを修正し、より明確な例を追加する必要がありました。

元の仕様書では const Θ float64 = 3/2 の結果が 1.5 とされていましたが、Goの定数評価規則に従うと、32 はどちらも型を持たない整数定数であるため、3/2 は整数除算として評価され、結果は 1 となります。この 1float64 型に変換されて Θ に代入されるため、最終的な値は 1.0 となるのが正しい挙動です。

この不正確な記述を修正し、さらに浮動小数点除算を行うための正しい方法(例: 3/2.)を示すことで、読者がGoの定数評価規則を正確に理解できるようにすることが目的でした。

前提知識の解説

このコミットの変更内容を理解するためには、以下のGo言語の基本的な概念を理解しておく必要があります。

  • Go言語の定数 (Constants): Go言語には、コンパイル時に値が決定される定数があります。定数には「型付き定数 (typed constants)」と「型なし定数 (untyped constants)」の2種類があります。
    • 型なし定数: リテラル(例: 10, 3.14, "hello") や、型なし定数のみで構成される式の結果は、デフォルトでは型を持ちません。これらは、より大きな精度で表現され、必要に応じて型が推論されたり、型付きの変数に代入される際に型変換が行われたりします。
    • 型付き定数: const x int = 10 のように明示的に型が指定された定数です。
  • 数値定数の「種類 (kind)」: 型なし数値定数には、integerfloating-pointcomplex のいずれかの「種類」があります。これは、その定数が整数、浮動小数点数、複素数のいずれとして扱われるかを示します。
  • 除算演算子 (/): Go言語における除算演算子 / の挙動は、オペランドの型(または種類)によって異なります。
    • 整数除算: 両方のオペランドが整数型(または型なし整数定数)の場合、結果は整数となり、小数点以下は切り捨てられます(ゼロ方向への切り捨て)。例: 3 / 21
    • 浮動小数点除算: 少なくとも一方のオペランドが浮動小数点型(または型なし浮動小数点定数)の場合、結果は浮動小数点数となります。例: 3.0 / 23 / 2.03.0 / 2.01.5
  • 型変換 (Type Conversion): Go言語では、異なる型の値の間で代入や演算を行う場合、明示的な型変換が必要となることがあります。ただし、型なし定数は、型付きの変数に代入される際に、その変数の型に自動的に変換されます。この際、値が変換先の型で表現可能であれば変換が成功します。

技術的詳細

このコミットの核心は、Go言語のコンパイラが定数式をどのように評価するか、特に除算演算子 / のセマンティクスにあります。

Go言語の仕様では、型なし定数を含む式は、その式全体が型なしのまま評価されます。そして、その結果が型付きの変数に代入される際に、初めて型が確定します。

元の例: const Θ float64 = 3/2

  1. 3 は型なし整数定数。
  2. 2 は型なし整数定数。
  3. 3/2 という式は、両方のオペランドが型なし整数定数であるため、整数除算として評価されます。結果は 1 という型なし整数定数になります。
  4. この型なし整数定数 1float64 型の定数 Θ に代入されるため、1float64 型に変換され、1.0 となります。 したがって、Θ の値は 1.0 が正しいです。

修正後の追加例: const Π float64 = 3/2.

  1. 3 は型なし整数定数。
  2. 2. は小数点が付いているため、型なし浮動小数点定数。
  3. 3/2. という式は、オペランドの一方が型なし浮動小数点定数であるため、浮動小数点除算として評価されます。結果は 1.5 という型なし浮動小数点定数になります。
  4. この型なし浮動小数点定数 1.5float64 型の定数 Π に代入されるため、1.5 はそのまま float64 型の値として Π に設定されます。 したがって、Π の値は 1.5 が正しいです。

この変更は、Go言語の仕様が、コンパイル時の定数評価の厳密なルールを反映していることを示しています。特に、数値リテラルの記述方法(整数か浮動小数点か)が、そのリテラルを含む式の評価結果に直接影響を与えるという重要な点を強調しています。

コアとなるコードの変更箇所

変更は doc/go_spec.html ファイルの以下の部分です。

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
  "Title": "The Go Programming Language Specification",
-"Subtitle": "Version of November 1, 2012",
+"Subtitle": "Version of November 17, 2012",
  "Path": "/ref/spec"
 }-->
 
@@ -3656,7 +3656,8 @@ complex, or string constant).\n const a = 2 + 3.0          // a == 5.0   (untyped floating-point constant)\n const b = 15 / 4           // b == 3     (untyped integer constant)\n const c = 15 / 4.0         // c == 3.75  (untyped floating-point constant)\n-const Θ float64 = 3/2      // Θ == 1.5   (type float64)\n+const Θ float64 = 3/2      // Θ == 1.0   (type float64, 3/2 is integer division)\n+const Π float64 = 3/2.     // Π == 1.5   (type float64, 3/2. is float division)\n const d = 1 &lt;&lt; 3.0         // d == 8     (untyped integer constant)\n const e = 1.0 &lt;&lt; 3         // e == 8     (untyped integer constant)\n const f = int32(1) &lt;&lt; 33   // f == 0     (type int32)\n```

## コアとなるコードの解説

*   **`"Subtitle": "Version of November 1, 2012"` から `"Subtitle": "Version of November 17, 2012"` への変更**:
    これは仕様書自体のバージョン日付の更新であり、ドキュメントのメタデータに関する変更です。このコミットが2012年11月17日に行われたことを反映しています。

*   **`const Θ float64 = 3/2 // Θ == 1.5 (type float64)` の修正**:
    この行は、Go言語の定数評価における整数除算の挙動を正確に反映するように修正されました。
    `3/2` は、両オペランドが型なし整数定数であるため、整数除算として評価され、結果は `1` となります。この `1` が `float64` 型に変換されるため、最終的な `Θ` の値は `1.0` となります。コメントが `// Θ == 1.0 (type float64, 3/2 is integer division)` に変更されたことで、この挙動が明確に説明されています。

*   **`const Π float64 = 3/2. // Π == 1.5 (type float64, 3/2. is float division)` の追加**:
    この新しい行は、浮動小数点除算を行うための正しい方法を示しています。
    `3/2.` のように、少なくとも一方のオペランド(この場合は `2.`)を浮動小数点リテラルとして記述することで、式全体が浮動小数点除算として評価され、結果は `1.5` となります。この `1.5` が `float64` 型に変換されるため、最終的な `Π` の値は `1.5` となります。この例は、Go言語で意図的に浮動小数点除算を行いたい場合の記述方法を明確に示しています。

これらの変更により、Go言語の定数評価、特に除算における型なし定数の挙動に関する仕様書の記述が、より正確で理解しやすいものになりました。

## 関連リンク

*   Go言語の公式ウェブサイト: [https://golang.org/](https://golang.org/)
*   Go言語の仕様書: [https://golang.org/ref/spec](https://golang.org/ref/spec) (このコミットで変更されたドキュメントの最新版)
*   Go Change List 6782084: [https://golang.org/cl/6782084](https://golang.org/cl/6782084)

## 参考にした情報源リンク

*   コミット情報: `./commit_data/14432.txt`
*   GitHubコミットページ: [https://github.com/golang/go/commit/2ae61d557aec846b9b7970022aaa0c28f17546de](https://github.com/golang/go/commit/2ae61d557aec846b9b7970022aaa0c28f17546de)
*   Go言語の仕様書 (一般的な知識として): [https://golang.org/ref/spec](https://golang.org/ref/spec)