📄 fn.html~
字号:
<html>
<head>
<title>BT2IL::Float Number 浮点数部分</title>
<link rel="stylesheet" href="bt2il.css" type="text/css">
</head>
<body>
<h1>BT²IL::Float Number 浮点数部分</h1>
<p>这一部分相当有趣,包含最常见的一些数学公式,也许可以看成是“编译
期的数学库”,compile-time math library,简称“CTML”?</p>
<p>关于浮点数的大概分成五个部分,基本运算、三角函数、指数对数、常量
和其它运算。基本运算包含了基本的四则运算、大小比较,以及浮点数的分拆;
三角函数包含了 sin、cos、tan 和 arcsin;指数对数包含了自然指数、自然对
数、常用对数、幂指数,以有开方运算;常量有π、e 等;其它运算有阶乘等。
</p>
<p>这些运算应该能达到至少 14 位数的精度;多数应该能达到 double 的最
高精度。不过,目前为止,我还没有提供一个错误检测机制,比如防止 ln 的参
数为负。</p>
<p>所有有关浮点数的运算,都在 namespace btil::fn 中。</p>
<h2>浮点数的表示</h2>
<p>浮点数并不能直接作为模板参数来处理,这样也就限制了在编译期计算中
进行浮点运算。解决的办法就是把浮点数隐藏于一个类中,然后以此类作为模板
的参数再传递。虽然如此,在模板特化时,还是极为不方便。注意,在些所说的
“浮点数”最可能是一个类型!如果说到浮点值,才可能是一个具体的如
double 的值。下面是一个典型的“浮点数”:</p>
<pre class="example-code">// 浮点数
struct float_number
{
static const double f_val = 1.414; // 必须是 f_val
};
</pre>
<p>实际上,浮点数可以这样定义:只要含有类型为 static const double 的
成员“f_val”的类,都可称为“浮点数”(Float Number),f_val 为其浮点
“值”。</p>
<h2><a href="fnexp.html">指数对数运算</a></h2>
<h2><a href="fnbase.html">浮点数基本运算</a></h2>
<p>浮点数的基本运算中有加、减、乘、除、取负、相等比较等。</p>
<h3>加减乘除</h3>
<p>加、减、乘、除四个运算极为相似,都是需要两个参数,结果当然也是浮点
数了。</p>
<p>例子:</p>
<pre class="example-code">// 加 减 乘 除
btil::fn::plus<f1, f2>::value // f1+f2 的结果
btil::fn::minus<f1, f2>::value // f1-f2 的结果
btil::fn::multiplies<f1, f2>::value // f1*f2 的结果
btil::fn::divides<f1, f2>::value // f1/f2 的结果
plus<f1, f2>::value::f_val // f1+f2 的结果的值
struct one { static const double f_val = 1.0; } // 两个浮点数
struct two { static const double f_val = 2.0; }
minus<two, plus<divides<one, two>::value, one>::value
>::value::f_val == 0.5;
</pre>
<h3>取负</h3>
<p>取负运算就是取一个浮点数的负数。</p>
<p>例子:</p>
<pre class="example-code">// 取负
btil::fn::negate<f>::value // -f 的结果
negate<one>::value::f_val == -1.0;
negate<two>::value::f_val == -2.0;
</pre>
<h3>相等比较</h3>
<p>比较两个浮点数是否相等。当然了,是近似相等。比较的办法是把两个数相
除,然后再去与 1 比较,如果相差在 1E-16 之内,则认为相等。注意,这个的
结果是布尔值(true 或 false)。</p>
<p>例子:</p>
<pre class="example-code">// 浮点数 相等比较
btil::fn::equal<f1, f2>::value // f1 与 f2 是否近似相等
equal<one, two>::value == false;
equal<one, one>::value == true;
</pre>
<h2>浮点数开平方运算</h2>
<p>浮点数开平方的公式跟整数开平方是一样的,只是终止的条件变得更严格、
更复杂了。不过,浮点数的一个好处是,只要 x 与 x' (近似)相等就可以认为
找到结果了。</p>
<p>例子:</p>
<pre class="example-code">// 浮点数开平方
btil::fn::sqrt<f>::value // f 的平方根
sqrt<one>::value::f_val == 1.0;
sqrt<two>::value::f_val == 1.41421356237309490;
</pre>
<h2>π 及角度</h2>
<h3>π</h3>
<p>很简单,就一个常数,π。只不过,这个常数是求出来的,还好精度不错,
精确到了 15 位数以上。</p>
<p>例子:</p>
<pre class="example-code">// pi
btil::fn::pi // 浮点数 pi
pi::f_val == 3.14159265358979360;
</pre>
<h3>角度</h3>
<p>提供从角度到弧度的转换。角度暂时是整数。</p>
<p>例子:</p>
<pre class="example-code">// 角度
btil::fn::angle<N>::value // 角度 N 的弧度数
angle<180>::value::f_val == pi::f_val;
angle<90>::value::f_val == pi::f_val / 2.0;
</pre>
<h2>三角函数</h2>
<p>三角函数中的 sin、cos 和 tan。参数是弧度值。</p>
<p>例子:</p>
<pre class="example-code">// 三角函数 sin cos tan
btil::fn::sin<f>::value // 弧度 f 的 sin 值
btil::fn::cos<f>::value // 弧度 f 的 cos 值
btil::fn::tan<f>::value // 弧度 f 的 tan 值
sin<angle<30>::value>::value::f_val == 0.5;
sin<angle<60>::value>::value::f_val == 0.866025403784439;
sin<angle<90>::value>::value::f_val == 1.0;
cos<angle<75>::value>::value::f_val == 0.25881904510252;
sin<angle<15>::value>::value::f_val == 0.267949192431123;
</pre>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -