浮動小数点数の規格です。 ⇒ [[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)