繰り返し 2 乗で 掛ける 回数を 減らし、 x の n 乗を求める
小数 x と、
海外で定番の問題リスト 4 本には入っていません
問題
数をx とn をx の n 乗を**、Math.pow、math.Pow) は
nが 0 なら 1 を返しますnが負なら、 xの-n乗の逆数を 返します。 この とき xは 0 ではありません xは -100 より大きく 100 より 小さい 数、 nは -2147483648 以上 2147483647 以下です- 答えの
絶対値は 10000 以下に 収まる ものとします
入力と出力の例
例 1
0.5 を 3 回掛けて 0.125 です。
例 2
負の
例 3
n が
面接での聞かれ方
面接では、
- 「
pow(x, n)を自分で 書いてください」 - 1
回ずつ掛ける 書き方を 見せると、 「n が 20 億だったら?」と 聞かれます - 「n が負のときは?」
「n が いちばん 小さい 負の 数の ときに、 符号を 反転できますか?」と、 端の 場合を 詰められます
芯は、
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
アルゴリズムのチートシートの「配列と文字列」に、
関わる学び
配列と
まず 考える手順
段 1
素直に x を n 回掛けるn が 20 億を
段 2
x¹³ は、base を x からn のn を 1 ビット右へずらします。
段 3
n がx を 1 / x にn を -n にn が -2147483648 の-n は 32 ビットのint (64 ビット) なら
解答
Python
Python
def fast_power(x, n):
if n < 0:
x = 1 / x
n = -n
out = 1.0
base = x
while n > 0:
if n & 1:
out *= base
base *= base
n >>= 1
return outJavaScript
JavaScript
function fastPower(x, n) {
if (n < 0) {
x = 1 / x;
n = -n;
}
let out = 1;
let base = x;
while (n > 0) {
if (n % 2 === 1) {
out *= base;
}
base *= base;
n = Math.floor(n / 2);
}
return out;
}Go
Go
func fastPower(
x float64, n int,
) float64 {
if n < 0 {
x = 1 / x
n = -n
}
out := 1.0
base := x
for n > 0 {
if n&1 == 1 {
out *= base
}
base *= base
n >>= 1
}
return out
}JavaScript の & と >> は 32 ビットのn が 2147483648 の% 2 と 2 で
計算量
- 時間は O(log n) です。
1 回まわる ごとに nが半分に なり、 nが 20 億でも 32 回ほどで終わります - 使う
記憶は O(1) です。 outとbaseだけです - 再帰で
「 nが偶数なら x^(n/2) を 2 乗、 奇数ならさらに x を 掛ける」と 書いても 同じ O(log n) ですが、 呼び出しの 深さの 分 O(log n) の 記憶を使います
よく ある間違い
- 1
回ずつ掛ける。 nが大きいと 間に 合いません。 nが 2147483647 なら、掛け算を 20 億回します - 負の
nを忘れる。 例 3 で、while n > 0に一度も 入らず 1 を 返してしまいます。 先に 逆数と 符号の 反転をします - 32 ビットの
整数で -nを作る。nが -2147483648 だと、反転しても 32 ビットに 入らず あふれます。 64 ビットの 型に 移してから 反転します - JavaScript で
ビット演算を使う。 n >> 1はnを 32 ビットに切るので、 nが 2147483648 のとき負に なって 繰り返しが すぐ 終わります
解答を動かした版 Python 3.14.7Node.js 24.22.1Go 1.24.2確認日 2026年11月8日
面接での 話し方の例
書き始める
「1
回ずつ掛けると n 回かかるので、 n を 2 進で 見ます。 x を 毎回 2 乗しながら、 n の 下の ビットが 1 の ときだけ 答えに 掛け、 n を 半分に していきます。 n が 負なら、 先に x を 逆数に して n の 符号を 反転します。 いちばん 小さい 負の 数でも 反転できるよう、 64 ビットの 整数で 持ちます。 時間は O(log n)、 記憶は O(1) です。」
書き終えたら、
「例 2 の -2 の 5 乗を
たどります。 5 は 2 進で 101 です。 下の ビットが 1 なので 答えに -2 を 掛けて -2、 baseは 4、nは 2 です。次の ビットは 0 なので 掛けず、 baseは 16、nは 1 です。最後の ビットは 1 なので 16 を 掛けて -32 です。」