במספר הקסום, אם ניקח את האקספוננט המספר הוא 190,
עכשיו הshift הוא למעשה חלוקה ב2 של האקספוננט, ואז אנו מחשבים
190-E/2 אם נתייחס לכך ש הe האמיתי הוא E=e+127 אז נקבל
NewE=190-63-e/2=127-e/2
ואז Newe=-e/2
כלומר אם זה היה השינוי היחיד, היינו מקבלים קירוב טוב, לחישוב 1 חלקי שורש המספר,
פשוט על ידי שינוי ה exponent.השינוי במנטיסה הוא יותר מסובך. הסיבית התחתונה של האקספוננט נכנסת למנטיסה,
החלק של המספר הקסום הוא 0.43 וקצת אז המנטיסה החדשה(במקרה וסיבית האקספוננט 0)
f2=1.43 - (f-1)/2
כאשר המספר המקורי היה: v=f*2^e
בהחלט יתכן שהחלק התחתון נבחר כך שהמנטיסה תתעוות כמה שפחות. עבור מנטיסה 1.3 השינוי
כמעט שלא קיים. ניתוח ממש של מה שקורה במנטיסה אין לי, אבל וודאי שהוא פחות חשוב
שכן אנחנו בשלב זה רק צריכים קירוב טוב, והמנטיסה וודאי יש לה ערך של בין 1 ל 2.
כמובן שאחרי הניחוש המקורי אנו מבצעים איטרציה בודדת של שיטה איטרטיבית בשביל
לשפר את הדיוק.
היופי בקוד הנ"ל הוא המהירות המדהימה שלו, אין אף חילוק של משתני נקודה צפה,
אם נרצה לממש בעזרת קוד זה sqrt מלא ומדויק. נצטרך להוסיף 2 איטרציות(סך הכל 3)
ולהוסיף חילוק אחד בסוף.
נקבל:
float M_sqrt( float number ) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( long * ) &y; /* evil floating point bit level hacking*/ i = 0x5f3759df - ( i >> 1 ); // turn E to -E/2. and F to y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); /* 1st iteration*/ y = y * ( threehalfs - ( x2 * y * y ) ); /* 2nd iteration*/ y = y * ( threehalfs - ( x2 * y * y ) ); /* 3rd iteration*/ return 1/y; }
|