nビット列で表せる負の数(2の補数表現)の最大値を、10進数で返却してくれる関数をjsで定義してみたところ少しハマった。
例えば、8ビットの2の補数表現で表せる範囲は-128~127である。
式で範囲を表すと「-2^(n-1) ~ 2^(n-1) – 1」となる。
だから、8を渡したら-128を返す関数があったら便利では?と思った。
定義をしてみたところ見慣れないエラーが出た。
function n2(n) { return -2 ** (n - 1); }
Uncaught SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence
google先生翻訳「べき乗式の直前に使用される単項演算子。演算子の優先順位を明確にするために括弧を使用する必要があります」
符号がついている値のべき乗もカッコをつけないといけないらしい。-2を二乗した4を得たいのか2を二乗した値にマイナス符号をつけた値が欲しいのかによって書き方が異なる。言い方を変えると-1*(n**2)と(-n)**2は結果が異なる。-符号付きで二乗すると、マイナスが打ち消されてプラスになるのでnが偶数のときはプラスに奇数の時はマイナスになってしまう。今回は常に負数が欲しいので後者の演算が正しい演算順序である(こういう観察から結論を導いているので数学的には正しくない推論?な気がする…)。
演算の順番大事。ちなみにjsの掛け算(& べき算)は左側から演算されるらしい。
例えば、
(1)
function n2(n) { return -(2) ** (n - 1); }
(2)
function n2(n) { return -1(2) ** (n - 1); }
このように(1)や(2)のような省略した書き方は、できないようです。。
function n2(n) { return -1 * (2) ** (n - 1); }
と記述することで意図したとおりの表示がされたが、
-1 * (2) ** n(n – 1) って、
ぱっと見で、何を意図しているのかすごい分かりにくい気がする。
// 負数の最大値は-2^n-1で表せるがjsの場合は -1 * (2 ** (n - 1)) と表現する必要がある function n2(n) { return -1 * (2 ** (n - 1)); }
って描いたほうが-1の意図が分かりやすいかな…プログラミングで数式を表す場合というか数式は、
変数の意図が描いてないので後から見てもなんでこうしたのか分かりにくい気がする。
※最後になぜか愚痴に近い言い方になったが課題が残った。。。
コメント