Skip to content

50. Pow(x, n)#43

Open
tom4649 wants to merge 5 commits intomainfrom
50.Pow
Open

50. Pow(x, n)#43
tom4649 wants to merge 5 commits intomainfrom
50.Pow

Conversation

@tom4649
Copy link
Copy Markdown
Owner

@tom4649 tom4649 commented Apr 5, 2026

Comment thread 50/sol2.py
if n == 0:
return 1.0
if n < 0:
return 1.0 / self.myPow(x, -n)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的には return self.myPow(1.0/x, -n) の方が好みです。
x^n = (1/x)^(-n) と書く方が、x^n = 1 / (x^(-n)) より自然だと思ったからです

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そちらを自然だと考える理由はなるほどです。
しかし逆数をとった時に生じる誤差が累積されることも考えて今回はこのままにしておこうと思います。
こういう複数の選択肢を選べるようにしておきたいです。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

オーバーフローを引き起こしているので、ここでは良い選択肢とは言えないかもしれません。

「指数を半分にしつつ、底を毎回 x**2 に置き換える」やりかただとオーバーフローが生じたので、底を変えない形にした

こちらについてですが、オーバーフローした時に、**演算だとエラーを投げますが、*演算だとinfを返すので結果的に治っているという形かと。数値的にはpow(x ** 2, n // 2)も、pow(x, n // 2) ** 2も同じですよね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ご指摘の通りで、x*xを渡すようにしたらエラーはなくなりますね。

**演算だとエラーを投げますが、*演算だとinfを返す

これは知らなかったです。勉強になりました

Comment thread 50/sol2.py
half = self.myPow(x, n // 2)
if n % 2 == 1:
return half * half * x
return half * half
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x^n * y を計算するヘルパーを定義する方法もありますね

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これを用いると末尾最適化ができそうですが、Pythonでは末尾最適化が行われないので、Trampolineという手法があることを知り、これを使って実装してみました

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trampoline 知らなかったので勉強になりました!

Comment thread 50/memo.md

https://github.com/hroc135/leetcode/pull/43/changes#diff-788d4e4d3d8fc9d0d4ea879b815deba3b2c21e39a44274fe799eaa496c5d2e43

組み込み関数のコードを読んでいる
Copy link
Copy Markdown

@hroc135 hroc135 Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 組み込み関数ではなく、標準ライブラリですね。少なくとも自分が良く扱う言語ではここの区別はできた方がいいと思いました!

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

math.Powとありましたね。失礼しました。

Comment thread 50/memo.md Outdated

sol2.pyを再帰でかいた。

「指数を半分にしつつ、底を毎回 x**2 に置き換える」やりかただとオーバーフローが生じたので、底を変えない形にした
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これはもうちょっと深掘りしてほしいですね。x * xで底を渡してやると動くと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここでもコメントいただいていましたね、すみません。上で返答させていただきました。

Comment thread 50/sol1_revised.py Outdated
shifted = abs(n)
current_pow = x
while shifted > 0:
if shifted & 1:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これはなんらかの意図で、//%ではなく、ビット演算を行なっているんですかね?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ビット演算の方が高速だと思います。また//や%よりも一般的だと個人的には思います

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自分の感覚だと%の方が直感的だと思いました

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

直感的なのは剰余演算かもしれないですね。Pythonは高速化の恩恵がなさそうなので%で十分かもしれません

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

どちらが一般的かは文脈によると思いますが、この問題の場合だと、x^2n = (x^n)^2, x^(2n+1)=x(x^n)^2を素直に表現するなら、//, %かなと。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ビット演算はCPUの動作に忠実で効率も良いため計算の意図を正確に表す書き方だと思っていました。
どちらも選べるようにしておこうと思います。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2進数のメンタルモデルで考えているなら、ビット演算で処理をするのも自然だと思います。この問題だとどっちもありに思いました。扱っている対象の抽象度に応じて適切な表現は変わりそうですね。

Comment thread 50/sol1_revised.py Outdated
Comment on lines +4 to +5
shifted = abs(n)
current_pow = x
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

変数名がイマイチに感じます。下のhalfも同様です。

shifted: the variable I'm going to shift later. I won't tell you what it is, though. No spoiler.
って感じですね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shiftedはexponentにしました。halfは個人的にはこれで良いかと思ったので差し当たりこのままにしておきます。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一応、何が違和感があるのか説明しますと、半分にしたのは、指数部分ですよね。2^2を2^4の半分とは呼びませんよね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修正しました。ご指摘ありがとうございます。

Comment thread 50/sol2.py
if n == 0:
return 1.0
if n < 0:
return 1.0 / self.myPow(x, -n)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的には、引数を書き換えるために関数を再帰的に呼ぶのは、ややパズルに感じます。引数を直接書き換えてしまったほうがシンプルに感じます。

if n < 0:
    x = 1.0 / x
    n = -n

趣味の範囲かもしれません。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど、再帰的に呼ばなくても解決するのですね。気づきませんでした。
revisedのファイルで採用させていただきました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants