- 追加された行はこの色です。
- 削除された行はこの色です。
浮動小数点数の規格です。 ⇒ [[WikiPedia.ja:IEEE_754]]
** 算出 [#hfc0aa96]
整数だけで算出する方法です。 ⇒ [[関連日記>http://gir-lab.spaces.live.com/blog/cns!63A4C32EDA5CF2F7!624.entry]]
+ 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)