する#include <stdio.hに> する#include <string.hの> する#include <STDLIB.H> / * atof * / / * 计算= 1 / SQRT(N) * / float型Q_rsqrt(浮動小数点数) { 長いI。 フロートX2、Y。 constのフロートthreehalfs = 1.5F; X2 =数* 0.5F。 Y =番号。 I = *(長い*)&Y。 //悪浮動小数点ビットレベルハッキング I = 0x5f3759df - (I >> 1)。//何ファック? Y = *(フロート*)&I。 Y = Y *(threehalfs - (X2 *のYの*のY))。 //第一反復 // Y = Y *(threehalfs - (×2 * yをする* yを)); //第二の繰り返し、これを除去することができる Q3_VM #ifndefを __linux__ #ifdefの のassert(!ISNAN(Y)); // bk010122 - FPE? #endifのは #endifの Yを返します。 } int型のmain(int型ARGC、チャーCONST * ARGV []) { F9 = 81.0fフロート。 F9 = Q_rsqrt(F9)。 printf( "F9 =%Fを\ n"、F9)。 0を返します。 }
結果:
F9 = 0.111086
1/9 = 0.111111に非常に近いコンピュータと1 / SQRT(81)
SQRT()関数を比較すると、このアルゴリズムは、ほぼ4倍の速さで、あなたが知っている、それはコンパイラの機能が付属していますが、厳格かつ慎重な組み立てに最適化されたああて!
ニュートン反復法の原理は、値を推測し、この値から反復を作ることです。したがって、準推測値、反復数が少ないです。カーマックが一緒後者変位アルゴリズムを用いて、結果としてこの値を推測0x5f3759df選ん、Y得られ、1 / SQRT(N)に非常に近いです。このように、我々は唯一の私たちに必要な精度を達成することができます2回のニュートン反復法を必要としています。
関数が1 / SQRT(X)を返し、SQRT(X)よりも画像処理関数は、より有用です。
この正一度だけの繰り返し!(実際には、不使用の繰り返し、直接操作)することに注意してください。コンパイル、テストは、よくこれが4倍速くだけワーキンググループの数、および標準SQRT()関数の比ではありません!
この単純な数は、性交が文をマークされているものを、最も中心と最も不可解を与えられたI = 0x5f3759df - (I >> 1 ); プラスY = Yの*(threehalfs - ( ×2 *のy * yを))。
2つの文平方根計算を完了するために!また、フレーズが速く、コアシフト演算であることに注意してください!具体的には、命令を掛けていない多くのRISCアーキテクチャのCPUは、これは非常に効率的です。
アルゴリズムの原理は、(X)/ F「(x)が連続的に近似F(x)がルート= XFを使用して、ニュートン反復法を使用することです。
平方根を取る:Fを(X)= X ^ 2 = A、F '(x)= 2 * X、F(X)/ F'(X)= X / 2、(x)はXFに置換されているF(X)/ F「(X)/ 2(X + A / X)を有し、
今、私たちは= 5を選択し、その後、私たちは5/2 = 2.5を数えることができる、など2として、推測を選択し、(2.5 + 2)/ 2 = 2.25; 5 / 2.25 = ......この繰り返しが続く、結果はに収束しますSQRT(5)。
しかし、カーマックの作者は本当に彼は神秘的な定数0x5f375a86計算その夢「値、選択した強力な場所である
ことは、我々は1 / SQRT(N)に非常に近い計算値を行コメントを追加しましたラインであるが、我々は唯一の2倍を必要としますニュートン反復は、私たちに必要な精度を達成することができます。