Crazy Code to Calculate 1/√x [English Subtitles]

แชร์
ฝัง
  • เผยแพร่เมื่อ 15 พ.ย. 2024

ความคิดเห็น • 87

  • @NE-fy9cj
    @NE-fy9cj 3 วันที่ผ่านมา +166

    平方根はlogにすると計算しやすくて、一方floatのlogを取ってlog(1+x)のマクローリン展開による近似を適用すると上手いこと元の数のlongが現れて、さらにニュートン法で精度を高くしてるのか
    もうこれ書いた人機械語話せる数学者やろ

    • @collectedby8655
      @collectedby8655 3 วันที่ผ่านมา +71

      このプログラムを書いた人も起源は知らずに使っていて、本当の元はどっかの大学の数学者だったはずです。その論文は有名になりませんでしたがゲームのような誤差があまり気にならないプログラムでは有用で、ソフトウェア会社で代々受け継がれていたとかだった気がします。

    • @ossss2985
      @ossss2985 3 วันที่ผ่านมา +17

      @@collectedby8655 やっぱ数学者って神だわ

    • @Anonymous-qx6xp
      @Anonymous-qx6xp 3 วันที่ผ่านมา +2

      logの底は2なのでマクローリン展開とかではないんじゃないかな

    • @ccxxii7816
      @ccxxii7816 3 วันที่ผ่านมา +6

      ​@@Anonymous-qx6xp 底の変換でも結局log(e,2)の定数で割ってるだけだし、割となんとかなりそう

    • @NE-fy9cj
      @NE-fy9cj 21 ชั่วโมงที่ผ่านมา +1

      ⁠​⁠@@Anonymous-qx6xp
      確かにと思って調べてみたら
      0< x=m/2^23

  • @ヘッドホン-n9f
    @ヘッドホン-n9f 3 วันที่ผ่านมา +147

    最後の「忘れろ」が趣深い

  • @t.s.55
    @t.s.55 3 วันที่ผ่านมา +74

    16億くらいの定数のところに書いてある
    “// what the fuck?”がおもろい

    • @可児風我
      @可児風我 2 วันที่ผ่านมา

      //なんこれ?

    • @Asakoto1849
      @Asakoto1849 วันที่ผ่านมา +1

      ​@@可児風我コメントであることを示す記号

    • @inti-lime61
      @inti-lime61 วันที่ผ่านมา +2

      @@Asakoto1849 いやまて、what the fuckを日本語訳しただけにも見える。。。

    • @Asakoto1849
      @Asakoto1849 วันที่ผ่านมา

      @@inti-lime61 そうでしたか…

  • @名字名前-s8t
    @名字名前-s8t 3 วันที่ผ่านมา +68

    想像より数倍変態的なコードだった
    floatの仕様の中身に手つっこんで裏技にしてるなんて…

  • @renyoko
    @renyoko 2 วันที่ผ่านมา +2

    これが何に使われてるのかをちゃんと説明してくれるの地味にありがたい、照明の処理に使われているけど詳しいことは省くって言うだけで終わらせることもできるだろうに…

  • @ぬぺ
    @ぬぺ 3 วันที่ผ่านมา +16

    数学と機械計算をグチャグチャにしていいとこどりしたコード好きだ

  • @y_nene
    @y_nene 2 วันที่ผ่านมา +6

    Inverse square rootで検索したらWiki立ってるのかよこのアルゴリズム……
    気の狂った遺物マジで大好き

  • @rice_Place
    @rice_Place 3 วันที่ผ่านมา +21

    この話知った時、このチャンネルで解説してくれないかなあと思ったので助かります

  • @collectedby8655
    @collectedby8655 3 วันที่ผ่านมา +20

    ポインタでキャストする理由は普通にキャストすると整数と小数の内部表現に合わせてキャストされますが、
    (1->1.0のように)
    ポインタでキャストすることで内部のbitそのままに型を変換できるからですね。

    • @とっぽ-x8g
      @とっぽ-x8g 3 วันที่ผ่านมา +5

      ポインタでのキャストはstrict aliasing ruleに反するので未定義動作ですね。
      ちゃんと実装するのであれば、C言語ならunionが使えます。
      C++の場合はunionでの変換も未定義動作なので、C++17以前はmemcpy、それ以降はstd::bit_castが使えます (コンパイラの最適化により実際にコピーは行われません)

    • @collectedby8655
      @collectedby8655 3 วันที่ผ่านมา +8

      @@とっぽ-x8g 僕に言われても困りますが💦
      動画のソースコードにもコメントでevil floating point bit level hackingって書いてありますね。

    • @soul_fb9990
      @soul_fb9990 2 วันที่ผ่านมา

      @@とっぽ-x8g std::bit_castの存在知らんかったから助かる……
      memcpy使って処理したら処理速度落ちるし、reinterpret_cast使ったら未定義動作だし……で妥協して無理やりキャストしてたのでマジで助かる

  • @aqua_length
    @aqua_length 3 วันที่ผ่านมา +8

    Inverse Square Rootだ!だいすきです!
    5:13
    知ってるだろうがでふふってなりました。

  • @qaultyo008
    @qaultyo008 วันที่ผ่านมา +2

    分子動力学の多重極子展開などで3次元座標にある2点間距離の逆乗を高速に求めたい時につかってました
    lapacあたりにも実装があった気がする
    あと数列の加速法とか補間あたりの分野も標本の数を変えずに予測精度を上げれんの?というワクワク感ありますよね。

  • @大野ひろき-y7w
    @大野ひろき-y7w 3 วันที่ผ่านมา +8

    変態ということだけ知ってたけど、ちゃんとした理屈があるってことに感動した。

  • @TumoiYorozu
    @TumoiYorozu 3 วันที่ผ่านมา +15

    rsqrt 命令と掛け算命令さえあれば、rsqrt(x) × x で sqrt(x) の代わりになったり、rsqrt(x) の2乗で1/x が求められたりと、2命令だけで sqrt も div も実現できてお得(sqrt も div も本来とても複雑な回路)

  • @Russelii
    @Russelii 2 วันที่ผ่านมา +1

    高速逆平方根の解説他でも見たけど難しかったけど、
    えびまラボさんの解説は無駄がない非常に簡潔だし、とてもわかり易かったです!
    むしろえびまラボさんでも8分かかるくらいの難しい話ってことか

  • @おれっち-s9o
    @おれっち-s9o 3 วันที่ผ่านมา +11

    なるほどlogを取ることで√の操作を1/2倍に置き換えることができるのか
    肝心のlogの操作は浮動小数点数の表記をそのまま整数として読めばできるから時間を短縮できると

  • @TNTSuperMan-Developers
    @TNTSuperMan-Developers 2 วันที่ผ่านมา +2

    そのWTFな逆平方根関数気になってました!
    プログラミングの勉強になりました!(ならない)
    解説ありがとうございます!

  • @Anonymous-qx6xp
    @Anonymous-qx6xp 3 วันที่ผ่านมา +2

    1+m/2^23が0以上1未満だから、e=floor(log2(y))+127、m/2^23=y*2^(127-e)-1で、i/2^23=e+m/2^23を具体的にyで表すことができる。Excelか何かでグラフを作ってみるとlog2(y)+Cを区分的に直線で表した関数になるのがよくわかる

  • @Coda-2
    @Coda-2 3 วันที่ผ่านมา +17

    マジックナンバー!
    ちょっと前にショート動画で見たやつだ
    floatの中身がそのまま使えるなんてよく気付いたよなぁ...

  • @lydialitvyak7750
    @lydialitvyak7750 6 ชั่วโมงที่ผ่านมา

    コメントの
    what the fuck?
    が好きすぎる

  • @A0ikun1818
    @A0ikun1818 2 วันที่ผ่านมา +4

    ちょうど1/√x+1/√y

  • @tatao5649
    @tatao5649 วันที่ผ่านมา +1

    超絶わかりやすい~!

  • @sy476
    @sy476 3 วันที่ผ่านมา +25

    実際今のCPU命令に√計算あるんでもう忘れて良いやつ

    • @aconite0988
      @aconite0988 2 วันที่ผ่านมา

      中身はもしかして同じようなことしてるのかな?

    • @resistan-y1h
      @resistan-y1h วันที่ผ่านมา +1

      マイコンとか組み込み系では使えそう。

    • @ああ-r9e1d
      @ああ-r9e1d 8 ชั่วโมงที่ผ่านมา

      @@resistan-y1hこれ

  • @匿名匿名-p9m
    @匿名匿名-p9m วันที่ผ่านมา

    1/√xで思い出したんですが、グラフィック系のシェーダープログラミングだと、rand関数がないので色々工夫して代用しているらしいです。それに関連してメルセンヌツイスターとかXORシフトあたりの乱数生成の解説も聞いてみたいです!ここ最近WGSLでパストレーサーを実装しようとしてるんですが、有名なfract-sinの擬似乱数だと周期性が気になるので他のアルゴリズムも知りたいと思ってます。

  • @tof1418
    @tof1418 3 วันที่ผ่านมา +12

    このアルゴリズムホント好き

  • @八木士
    @八木士 2 วันที่ผ่านมา +1

    ニュートン法は収束が早いってどっかで聞いたことがあるけどほんとに速いんだなあ

  • @andrew8128
    @andrew8128 3 วันที่ผ่านมา +2

    3:23 これ、初めて知ったときちょっと感動したのを思い出した。

  • @YOU-ur8vo
    @YOU-ur8vo 3 วันที่ผ่านมา +4

    ほんとこれ天才

  • @angiodianxin
    @angiodianxin 2 วันที่ผ่านมา +3

    03:35 の「ケチだね」、ふふってなる

  • @zankau9328
    @zankau9328 วันที่ผ่านมา +1

    C言語にはunionというものがあってだな

  • @AI-GHQ
    @AI-GHQ 11 ชั่วโมงที่ผ่านมา

    確かにすごいが、今はやってはいけない事に分類されるんだろうな。組み込みなど非力なマシンで高速化しようとしたらメモリ使うか、タイミング変えるか、何かをやめる位しかない。メモリ12kと言われて回路図見たら8kしかアクセスできず、アセンブラを削りまくった日々がよみがえる。

  • @N-EMPRESSEUR
    @N-EMPRESSEUR 3 วันที่ผ่านมา +2

    flootをlogの近似でlongに救出してニュートン法で帳尻合わせ、数値解析の演習でやりましたねえ
    もしかして数値計算やる人も、実はそんなに気にしていない・・・・・・?

  • @ててて-k2y
    @ててて-k2y 2 วันที่ผ่านมา +2

    キモすぎと気持ち良いが同時に来る

  • @CakeCh.
    @CakeCh. วันที่ผ่านมา

    これの応用で立方根を求める手法もありますよね。

  • @0408ranko
    @0408ranko วันที่ผ่านมา

    数学あるある証明を丁寧に解説してくれれば理解は出来るけど思い付くわけないだろシリーズ

  • @yamonton_9945
    @yamonton_9945 3 วันที่ผ่านมา +3

    解説されればまぁ分かる(分からん)のだけどこれをゼロから思いつくのは無理
    思考ルートが分からん

  • @分子軌道法
    @分子軌道法 3 วันที่ผ่านมา +7

    近似ってセンスやなあ

  • @ofoneDyag
    @ofoneDyag วันที่ผ่านมา

    &yのアドレスがfloatポインタ型だから、それをlongポインタ型にキャストした上で間接参照することで、yの中身自体もfloatからlongにキャストできるってことか?

  • @s009kawa
    @s009kawa 15 ชั่วโมงที่ผ่านมา

    対数だと計算が楽
    昔はコンピューターさんも計算尺を使っていたんですね

  • @星雲男子大学
    @星雲男子大学 3 วันที่ผ่านมา +2

    こういう、floatとかの「仕様」を利用した変態コードは、別環境に移植したときに(つまり仕様が変わったときに)正しく動作しなくなる可能性があるので、手放しで真似するのはやめましょう。
    組み込みプログラミングとかで「別環境への移植」が考えられない場合や、
    IEEEなどの規格を厳密に守られていることが保証されている環境間の移植しかありえない場合などは使えるので、そういったことを事前に検討してから使いましょう。

  • @enkero-q2c
    @enkero-q2c 3 วันที่ผ่านมา +18

    7行テトリスについて解説して欲しいです!

    • @evimalab
      @evimalab  3 วันที่ผ่านมา +18

      リクエストありがとうございます!お約束はできませんが、年内に出そうとしてみます。

  • @mekuri5767
    @mekuri5767 3 วันที่ผ่านมา +1

    正規表現の微分について解説してほしいです!

  • @あさひ-o8z
    @あさひ-o8z 3 วันที่ผ่านมา +1

    これは気持ちいい……

  • @kerokeroq
    @kerokeroq 3 วันที่ผ่านมา +1

    ある文字(二進数の組み合わせ)で表現された数字のlogをとったらその文字そのものが含まれてて、マジックナンバーはその残り物ってこと?

  • @totto2727
    @totto2727 3 วันที่ผ่านมา +2

    longのビット数って実行環境によって変わらなかったっけ…(32か64になることがほとんどだったと思いますが…)

    • @とっぽ-x8g
      @とっぽ-x8g 3 วันที่ผ่านมา +3

      そうですね、uint32_tを使うのが最適だと思います。
      floatと整数型のキャストも未定義動作なので、実際にはmemcpyなどを使う必要がありますね

    • @ccxxii7816
      @ccxxii7816 12 ชั่วโมงที่ผ่านมา

      そもそもこのコード自体32bit時代の話で独自命令も乏しかったらしいし、現代じゃ最初のチルノの書き方が何周も回って速くて確実なんだっけ?

  • @あい-d5f6q
    @あい-d5f6q 2 วันที่ผ่านมา +1

    「結果が分かりやすいし⑨で」

    • @匿名希望-z3n
      @匿名希望-z3n 2 วันที่ผ่านมา +1

      ぶっちゃけここのチルノは賢い……

  • @ルーカス-k1r
    @ルーカス-k1r 3 วันที่ผ่านมา +2

    精度の比較だけじゃなくて,実際の計算速度の比較も気になる

    • @soul_fb9990
      @soul_fb9990 3 วันที่ผ่านมา +10

      今のコンピュータでやってもあんまり効果は感じられないと思う。
      当時の掛け算割り算のコストがバカ高いコンピュータだからこそ価値がある感じのコード。
      弥生土器とかを見てロマンに浸ってる感じ。
      この動画は
      「昔は穴の中で火を焚べてたから縦長で重心低いんだなぁ」
      って紹介してる感じ。現代は平たいコンロで十分。

    • @ルーカス-k1r
      @ルーカス-k1r 2 วันที่ผ่านมา +1

      @ なるほど!

  • @d1Prczr6b29eM82Y
    @d1Prczr6b29eM82Y วันที่ผ่านมา

    世の中のエンジニアってこれをぱっと理解できるのか 土方には無理だなやっぱ

  • @user-yuuyuu1729
    @user-yuuyuu1729 3 วันที่ผ่านมา

    詳しくは分からんけど、すげぇってことは分かった.
    よく気がつくなぁ...

  • @明賀葵
    @明賀葵 2 วันที่ผ่านมา

    面白い

  • @アルト-b7w
    @アルト-b7w 3 วันที่ผ่านมา +1

    floatってどこから指数なのかどこで調べるの?

    • @KawaiiNegi-
      @KawaiiNegi- 3 วันที่ผ่านมา +2

      区切りが決まってる

    • @とっぽ-x8g
      @とっぽ-x8g 3 วันที่ผ่านมา +2

      C/C++におけるfloatは実装定義なので、残念ながら一般的な方法はありません。
      ただし、ほとんどの処理系ではfloatはIEEE754に従っているので、それを仮定すればよいです。
      C23/C++23以降であれば、それぞれIEEE754に従うことが規定されている _Float32, std::float32_t がありますが、そこまで気にする必要はないです

    • @星雲男子大学
      @星雲男子大学 3 วันที่ผ่านมา

      IEEEと呼ばれる「ルール」がある。

  • @うめはち
    @うめはち 2 วันที่ผ่านมา

    高速逆平方根!

  • @quartzhammar
    @quartzhammar 3 วันที่ผ่านมา +2

    日本語のはずなのに99.8%くらいわかんねぇ…

    • @大喜-n6y
      @大喜-n6y 3 วันที่ผ่านมา +3

      半分くらいはC言語やけどもな

  • @hitsuki_karasuyama
    @hitsuki_karasuyama 3 วันที่ผ่านมา

    高速逆平方根アルゴリズム

  • @user-777ntl
    @user-777ntl 3 วันที่ผ่านมา

    むずかしい…

  • @仮名ろはん
    @仮名ろはん 2 วันที่ผ่านมา

    はぇ〜すっごい実用的…

  • @zouo-from-Taikonotatsujin
    @zouo-from-Taikonotatsujin 3 วันที่ผ่านมา +2

    マジックナンバーは誤差吸収で
    真の技術結晶はマジックナンバー書いてある行のyの計算だったってこと?

  • @毛糸-c7l
    @毛糸-c7l 3 วันที่ผ่านมา

    こんなのよく気づくなあ

  • @yattinda
    @yattinda 3 วันที่ผ่านมา

    なるほどわからん