浮動小数点数の規格です。 ⇒ [[WikiPedia.ja:IEEE_754]]

** 算出 [#hfc0aa96]

整数だけで算出する方法です。

+ 2つの整数 a, b による浮動小数点数 a × 10&super{b}; を与える。
-- 例: 0.5 → 5 × 10&super{-1}; (a = 5, b = -1) 
+ c = 0 として a × 10&super{b}; × 2&super{c}; の形に変形する。
-- 例: 5 × 10&super{-1}; × 2&super{0}; 
+ b = 0 になるように a と c の値を調整する。
-- 例: 5 × 10&super{-1}; × 2&super{0}; → 10 × 10&super{-1}; × 2&super{-1};  → 1 × 10&super{0}; × 2&super{-1}; 
+ a × 2&super{c}; が得られる。
-- 例: 1 × 2&super{-1}; 
+ 最上位ビットの位置を合わせて浮動小数点表示にする。

*** C言語 [#hedb78d9]

このコードはパブリックドメインです。

 #include <stdio.h>
 #include <limits.h>
 
 #define EXP_DIGIT 8
 #define EXP_MAX ((1 << EXP_DIGIT) - 1)
 #define SIGN_DIGIT 23
 #define SIGN_MAX ((1 << SIGN_DIGIT) - 1)
 
 void Float(int s, int e10) {
   int sign = 0, e2 = 0, ss;
   if (s == 0) e10 = 0;
   if (s < 0) sign = 1, s = -s;
   while (s % 10 == 0) e10++, s /= 10;
   while (e10 != 0) {
     if (e10 < 0) {
       e2--, s *= 2;
       ss = s % 10;
       if (ss == 0 || s > INT_MAX / 2)
         e10++, s = (s / 10) + (ss >= 5 ? 1 : 0);
     } else if (e10 > 0) {
       if (s & 1 == 1 && s <= INT_MAX / 10)
         e10--, s *= 10;
       e2++, s = (s / 2) + (s & 1);
     }
   }
   while (s > 0 && s <= SIGN_MAX) e2--, s *= 2;
   while (s > SIGN_MAX * 2 + 1) e2++, s = (s / 2) + (s & 1);
   printf("%d-%d-%p\n", sign, e2 + SIGN_DIGIT + EXP_MAX / 2, s & SIGN_MAX);
 }
 
 int main() {
   printf("-0.1 => "); Float(-1, -1);
   printf("3.14159265 => "); Float(314159265, -8);
   return 0;
 }

*** [[LLPML]](簡略版) [#u3573ed5]

分割した比較が[[IEEE 754/比較]]にあります。&br;
簡略化については[[LLPML/簡略化]]を参照してください。

このコードはパブリックドメインです。

 <?xml version="1.0" encoding="utf-8" ?>
 <llpml version="0.10.20080205">
 
 <include src="stdio.xml" />
 
 <?llp
 printf("-0.1 => "); Float(-1, -1);
 printf("3.14159265 => "); Float(314159265, -8);
 
 //
 
 const int INT_MAX    = 0x7fffffff;
 const int EXP_DIGIT  = 8;
 const int EXP_MAX    = 0xff;
 const int SIGN_DIGIT = 23;
 const int SIGN_MAX   = 0x7fffff;
 
 function Float(s, e10) {
   var sign = 0, e2 = 0, ss;
   if (s == 0) e10 = 0;
   if (s < 0) sign = 1, s = -s;
   while (s % 10 == 0) e10++, s /= 10;
   while (e10 != 0) {
     if (e10 < 0) {
       e2--, s *= 2;
       ss = s % 10;
       if (ss == 0 || s > INT_MAX / 2)
         e10++, s = (s / 10) + (ss >= 5 ? 1 : 0);
     } else if (e10 > 0) {
       if (s & 1 == 1 && s <= INT_MAX / 10)
         e10--, s *= 10;
       e2++, s = (s / 2) + (s & 1);
     }
   }
   while (s > 0 && s <= SIGN_MAX) e2--, s *= 2;
   while (s > SIGN_MAX * 2 + 1) e2++, s = (s / 2) + (s & 1);
   printf("%d-%d-%p\n", sign, e2 + SIGN_DIGIT + EXP_MAX / 2, s & SIGN_MAX);
 }
 ?>
 
 </llpml>

*** [[LLPML]](従来版) [#u3573ed5]

分割した比較が[[IEEE 754/比較]]にあります。

このコードはパブリックドメインです。

 <?xml version="1.0" encoding="utf-8" ?>
 <llpml version="0.8.20070926">
 
 <!-- IEEE 754 single precision floating point -->
 
 <include src="stdio.xml" />
 
 <call name="printf"><string>-0.1 => </string></call>
 <call name="Float"><int>-1</int><int>-1</int></call>
 
 <call name="printf"><string>3.14159265 => </string></call>
 <call name="Float"><int>314159265</int><int>-8</int></call>
 
 <!-- -->
 
 <int-declare name="INT_MAX">0x7fffffff</int-declare>
 <int-declare name="EXP_DIGIT">8</int-declare>
 <int-declare name="EXP_MAX">0xff</int-declare>
 <int-declare name="SIGN_DIGIT">23</int-declare>
 <int-declare name="SIGN_MAX">0x7fffff</int-declare>
 
 <function name="Float">
   <arg name="s" />
   <arg name="e10" />
   <var-declare name="sign">0</var-declare>
   <var-declare name="e2">0</var-declare>
   <var-declare name="ss" />
   <if>
     <cond>
       <equal><var name="s" />0</equal>
     </cond>
     <block>
       <let><var name="e10" />0</let>
     </block>
   </if>
   <if>
     <cond>
       <less><var name="s" />0</less>
     </cond>
     <block>
       <let><var name="sign" />1</let>
       <let>
         <var name="s" />
         <sub>0<var name="s" /></sub>
       </let>
     </block>
   </if>
   <while>
     <cond>
       <equal>
         <mod><var name="s" />10</mod>
         <int>0</int>
       </equal>
     </cond>
     <block>
       <inc><var name="e10" /></inc>
       <var-div><var name="s" />10</var-div>
     </block>
   </while>
   <while>
     <cond>
       <not-equal><var name="e10" />0</not-equal>
     </cond>
     <block>
       <if>
         <cond>
           <less><var name="e10" />0</less>
         </cond>
         <block>
           <dec><var name="e2" /></dec>
           <var-mul><var name="s" />2</var-mul>
           <let>
             <var name="ss" />
             <mod><var name="s" />10</mod>
           </let>
           <if>
             <cond>
               <or>
                 <equal><var name="ss" />0</equal>
                 <greater>
                   <var name="s" />
                   <div><int name="INT_MAX" />2</div>
                 </greater>
               </or>
             </cond>
             <block>
               <inc><var name="e10" /></inc>
               <var-div><var name="s" />10</var-div>
               <if>
                 <cond>
                   <greater-equal>
                     <var name="ss" />
                     <int>5</int>
                   </greater-equal>
                 </cond>
                 <block>
                   <inc><var name="s" /></inc>
                 </block>
               </if>
             </block>
           </if>
         </block>
         <cond>
           <greater><var name="e10" />0</greater>
         </cond>
         <block>
           <if>
             <cond>
               <and>
                 <equal>
                   <and><var name="s" />1</and>
                   <int>1</int>
                 </equal>
                 <less-equal>
                   <var name="s" />
                   <div><int name="INT_MAX" />10</div>
                 </less-equal>
               </and>
             </cond>
             <block>
               <dec><var name="e10" /></dec>
               <var-mul><var name="s" />10</var-mul>
             </block>
           </if>
           <inc><var name="e2" /></inc>
           <let>
             <var name="s" />
             <add>
               <div><var name="s" />2</div>
               <and><var name="s" />1</and>
             </add>
           </let>
         </block>
       </if>
     </block>
   </while>
   <while>
     <cond>
       <and>
         <greater><var name="s" />0</greater>
         <less-equal>
           <var name="s" />
           <int name="SIGN_MAX" />
         </less-equal>
       </and>
     </cond>
     <block>
       <dec><var name="e2" /></dec>
       <var-mul><var name="s" />2</var-mul>
     </block>
   </while>
   <while>
     <cond>
       <greater>
         <var name="s" />
         <add>
           <mul><int name="SIGN_MAX" />2</mul>
           <int>1</int>
         </add>
       </greater>
     </cond>
     <block>
       <inc><var name="e2" /></inc>
       <let>
         <var name="s" />
         <add>
           <div><var name="s" />2</div>
           <and><var name="s" />1</and>
         </add>
       </let>
     </block>
   </while>
   <call name="printfln">
     <string>%d-%d-%p</string>
     <var name="sign" />
     <add>
       <var name="e2" />
       <int name="SIGN_DIGIT" />
       <div><int name="EXP_MAX" />2</div>
     </add>
     <and>
       <var name="s" />
       <int name="SIGN_MAX" />
     </and>
   </call>
 </function>
 
 </llpml>

** コメント [#r4f016d8]

//#comment(below)


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS