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

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

このコミットでは、doc/go_spec.html ファイルが変更されています。具体的には、2行の追加と2行の削除が行われています。

コミット

  • コミットハッシュ: 80a87a99cccc730980aae0b7b10c6e645869f755
  • Author: Matthew Dempsky mdempsky@google.com
  • Date: Sun Jan 6 16:56:06 2013 -0800

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

https://github.com/golang/go/commit/80a87a99cccc730980aae0b7b10c6e645869f755

元コミット内容

spec: Use "non-negative" instead of "positive"

Replacing division-by-power-of-2 with right-shift is valid for
zero too.

R=gri
CC=golang-dev
https://golang.org/cl/7027049

変更の背景

このコミットの主な目的は、Go言語の仕様書(doc/go_spec.html)における記述をより正確にすることです。具体的には、特定の最適化(2のべき乗による除算を右シフトに置き換える)が適用される条件について、「正の数(positive)」という表現を「非負の数(non-negative)」に修正しています。

この変更の背景には、コンパイラ最適化の正確性があります。2のべき乗による除算を右シフトに置き換える最適化は、被除数が0の場合にも有効です。しかし、従来の「正の数」という記述では、0が含まれないため、仕様と実際の最適化の適用範囲に齟齬が生じていました。この修正により、Go言語の仕様がコンパイラの挙動とより密接に一致し、曖昧さが解消されます。

前提知識の解説

1. 2のべき乗による除算とビット演算

コンピュータの内部では、数値の除算は比較的コストの高い演算です。しかし、除数が2のべき乗(例: 2, 4, 8, 16...)である場合、より高速なビット演算に置き換えることができます。

  • 右シフト (Right Shift): 整数を右に1ビットシフトすると、その値は2で割った商に相当します(整数除算の場合)。例えば、10 >> 15 です。10 >> 22 です。これは、10 / 2^110 / 2^2 と同じ結果になります。
  • ビットごとのAND演算 (Bitwise AND): 剰余(余り)を計算する場合、除数が2のべき乗であれば、ビットごとのAND演算を使用できます。例えば、N % 2^KN & (2^K - 1) と等価です。例えば、10 % 42 ですが、10 & (4 - 1) つまり 10 & 32 となります(バイナリで 1010 & 0011 = 0010)。

これらの最適化は、特に組み込みシステムや高性能が求められるアプリケーションにおいて、実行速度の向上に寄与します。

2. 「正の数」と「非負の数」

数学およびプログラミングにおいて、「正の数」と「非負の数」は異なる概念を指します。

  • 正の数 (Positive Numbers): 0より大きい数を指します。例: 1, 2, 3, ...
  • 非負の数 (Non-negative Numbers): 0以上の数を指します。例: 0, 1, 2, 3, ...

この違いは、特に境界条件(0を含むかどうか)を扱う際に重要になります。今回のコミットでは、0の場合も右シフトによる最適化が適用可能であるため、「非負の数」という表現がより適切であると判断されました。

技術的詳細

Go言語の仕様書は、Goコンパイラがコードをどのように解釈し、最適化できるかについての規範的なドキュメントです。このコミットは、Go言語のコンパイラが特定の除算操作を最適化する際の条件に関する記述を修正しています。

変更前の仕様では、「被除数が正の数(positive)であり、除数が2の定数べき乗である場合」に、除算を右シフトに、剰余をビットごとのAND演算に置き換えることができるとされていました。しかし、実際には被除数が0の場合でもこの最適化は有効です。

例えば、0 / 40 ですが、これを右シフトで表現すると 0 >> 20 となります。同様に、0 % 40 ですが、0 & (4 - 1) つまり 0 & 30 となります。このように、0は「正の数」ではありませんが、この最適化の対象となり得ます。

このため、仕様書を「被除数が非負の数(non-negative)であり、除数が2の定数べき乗である場合」に修正することで、Goコンパイラが0を被除数とする除算に対しても、より効率的なビット演算による最適化を適用できることを明確にしています。これにより、コンパイラの実装者は、仕様に準拠しつつ、より広範なケースで最適化を適用できるようになります。

この変更は、Go言語のセマンティクス(意味論)に直接的な影響を与えるものではなく、主にコンパイラの最適化の自由度と、その最適化が適用される条件の明確化を目的としています。

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

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of January 2, 2013",
+	"Subtitle": "Version of January 6, 2013",
 	"Path": "/ref/spec"\n }-->
 \n
 @@ -3027,7 +3027,7 @@ int64    -9223372036854775808
  <p>\n If the divisor is a <a href=\"#Constants\">constant</a>, it must not be zero.\n If the divisor is zero at run time, a <a href=\"#Run_time_panics\">run-time panic</a> occurs.\n-If the dividend is positive and the divisor is a constant power of 2,\n+If the dividend is non-negative and the divisor is a constant power of 2,\n  the division may be replaced by a right shift, and computing the remainder may\n  be replaced by a bitwise AND operation:\n  </p>\n```

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

このコミットでは、`doc/go_spec.html` ファイル内の2箇所が変更されています。

1.  **日付の更新**:
    ```diff
    -	"Subtitle": "Version of January 2, 2013",
    +	"Subtitle": "Version of January 6, 2013",
    ```
    これは、Go言語の仕様書のバージョン日付を更新したものです。これはコミットの主要な目的ではありませんが、ドキュメントの更新に伴う一般的な変更です。

2.  **主要な変更点 - 「positive」から「non-negative」への修正**:
    ```diff
    -If the dividend is positive and the divisor is a constant power of 2,
    +If the dividend is non-negative and the divisor is a constant power of 2,
    ```
    この行が、このコミットの核心となる変更です。
    変更前は、「被除数(dividend)が**正の数(positive)**であり、除数(divisor)が2の定数べき乗である場合」に、除算を右シフトに、剰余をビットごとのAND演算に置き換えることができると記述されていました。
    変更後は、「被除数(dividend)が**非負の数(non-negative)**であり、除数(divisor)が2の定数べき乗である場合」に修正されています。

    この修正により、Go言語の仕様において、被除数が0の場合でも、2のべき乗による除算が右シフトに、剰余がビットごとのAND演算に最適化されることが明確にされました。これにより、コンパイラは0を含む非負の整数に対して、より効率的なビット演算による最適化を適用することが可能になります。これは、Go言語のパフォーマンスとコンパイラの最適化能力に寄与する、細かではあるが重要な改善です。

## 関連リンク

*   Go Code Review 7027049: [https://golang.org/cl/7027049](https://golang.org/cl/7027049)

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

*   Go Code Review 7027049 の内容
*   Go言語の仕様書(変更前の内容を理解するため)
*   一般的なコンピュータサイエンスにおけるビット演算と除算の最適化に関する知識
*   「正の数」と「非負の数」の数学的定義