1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ruby の -1 ** 0.5 は虚数単位じゃない?!

1
Posted at

素朴な問いの意外な答

以下の Ruby コードを実行すると何が表示されるか?

p -1 ** 0.5

-1 を 0.5 乗するんだから,$(-1)^{0.5} = \sqrt{-1}$ だよね。
つまり,数学的には虚数単位になる。

Ruby って,確かこういうのを Complex で計算してくれるはず。
だから 0.0+1.0i が表示されるんじゃね?

と思ったのだが,実際は -1.0 が表示された。
ええっ?!

なぜこうなった?

ちょっと調べたところ,-1 ** 0.5 という式において,- は整数リテラル -1 の一部ではなく,単項演算子の - と解釈されるようだ。

そして,ここが重要なのだが,単項演算子の -** よりも結合の優先順位が低いのである。
だから

(-(1))**(0.5)

ではなく

-((1)**0.5)

という結合になる。

なぜ - が整数リテラルの始まりと解釈されない(そういうふうにパーサーを設計した)のかは謎。

- のあとが数字でなく

-x ** 0.5

とかなら分かるんだけど。

比較

ちなみに

-1 * 0.5

の場合,- は整数リテラル -1 の始まりだろうか,それとも整数リテラル 1 の前に置かれた単項演算子だろうか。
どちらと解釈しても計算結果は変わらないが,Ruby の解釈は前者である。
*** かだけの違いで全体の解釈がガラッと変わるのは面白い。
演算子として ** の優先順位が高いことともきっと関係があるのだろう。

おわりに

単項演算子も含めて,演算子の結合優先順位は気を付けているが,数字の前の - が単項演算子になるケースについて考えたことは無かった。
盲点だなあ。

関連して,以下の記事もよかったらどうぞ。
Ruby 使いがビビった Rust の -1_i32.abs() - Qiita

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?