📄 fn.hpp
字号:
// Float number implementation -*- C++ -*-
// Copyright (C) 2005 Ben T. Bear
//
// This file is published under GNU GPL 2.0. See more in "copy.hpp".
// #include "copy.hpp"
#ifndef __bt2il_fn_hpp
#define __bt2il_fn_hpp
namespace btil
{
namespace fn
{
/** float number
*
* a float number should be like this:
*
* struct float_number
* {
* static const double f_val = 1.0;
* };
*/
template <typename f1, typename f2>
struct plus;
template <typename f1, typename f2>
struct minus;
template <typename f1, typename f2>
struct multiplies;
template <typename f1, typename f2>
struct divides;
template <typename f>
struct negate;
template <typename f>
struct abs;
template <typename f1, typename f2>
struct equal;
template <typename f, int k = 10>
struct fn2em;
template <int k, int n>
struct __pow_kn;
template <typename f1, typename f2>
struct plus
{
struct value
{
static const double f_val = f1::f_val + f2::f_val;
};
};
template <typename f1, typename f2>
struct minus
{
struct value
{
static const double f_val = f1::f_val - f2::f_val;
};
};
template <typename f1, typename f2>
struct multiplies
{
struct value
{
static const double f_val = f1::f_val * f2::f_val;
};
};
template <typename f1, typename f2>
struct divides
{
struct value
{
static const double f_val = f1::f_val / f2::f_val;
};
};
template <typename f>
struct negate
{
struct value
{
static const double f_val = -f::f_val;
};
};
template <typename f>
struct abs
{
struct value
{
static const double f_val = ((f::f_val >= 0.0)
? f::f_val : -f::f_val);
};
};
template <bool zero, typename f1, typename f2>
struct __equal;
template <typename f1, typename f2>
struct equal
{
static const bool __z = (f1::f_val == 0.0) || (f2::f_val == 0.0);
static const bool value = __equal<__z, f1, f2>::value;
};
template <typename f1, typename f2>
struct __equal<true, f1, f2>
{
static const bool value = f1::f_val == f2::f_val;
};
template <typename f1, typename f2>
struct __equal<false, f1, f2>
{
static const double __e = f1::f_val / f2::f_val - 1.0;
static const bool value = (__e > -1E-16) && (__e < 1E-16);
};
template <int k, int n>
struct __pow_kn_p // n > 0
{
static const double __e = __pow_kn_p<k, n/2>::f_val;
static const double __b = (n % 2 == 0) ? 1.0 : k;
static const double f_val = __e * __e * __b;
};
template <int k>
struct __pow_kn_p<k, 0>
{
static const double f_val = 1.0;
};
template <bool neg, int k, int n>
struct __pow_kn_bool;
template <int k, int n>
struct __pow_kn_bool<true, k, n>
{
static const double f_val = 1.0 / __pow_kn_p<k, -n>::f_val;
};
template <int k, int n>
struct __pow_kn_bool<false, k, n>
{
static const double f_val = __pow_kn_p<k, n>::f_val;
};
template <int k, int n>
struct __pow_kn
{
struct value
{
static const double f_val = __pow_kn_bool<(n < 0), k, n>::f_val;
};
};
template <int t, typename f, int k>
struct __fn2em;
template <typename f, int k>
struct fn2em
{
static const double __f = f::f_val;
static const int sign = (__f < 0.0) ? -1 : (__f != 0.0);
static const double __x = (sign == -1) ? -__f : __f;
static const int __t = ((__x == 0.0) ? 0
: ((__x < 1.0) ? 1
: ((__x < k) ? 2 : 3)));
struct x
{
static const double f_val = __x;
};
static const int e = __fn2em<__t, x, k>::e;
struct m
{
static const double f_val = __fn2em<__t, x, k>::m::f_val * sign;
};
};
template <typename f, int k>
struct __fn2em<0, f, k> // less than 1
{
static const int e = 0;
struct m
{
static const double f_val = 0.0;
};
};
template <typename f, int k>
struct __fn2em<2, f, k> // [1.0, k)
{
static const int e = 0;
typedef f m;
};
template <typename f, int k>
struct __fn2em_s; // small than 1.0
template <typename f, int k>
struct __fn2em<1, f, k> // (0.0, 1.0)
{
static const int e = __fn2em_s<f, k>::e;
typedef typename __fn2em_s<f, k>::m m;
};
template <typename f, int k>
struct __fn2em_b; // big & equal than k
template <typename f, int k>
struct __fn2em<3, f, k> // [k, .....
{
static const int e = __fn2em_b<f, k>::e;
typedef typename __fn2em_b<f, k>::m m;
};
template <int n, typename f, int k>
struct __fn2em_s_n; // get pow_kn<2n> < f
template <int n, typename f, int k>
struct __fn2em_s_e;
template <typename f, int k>
struct __fn2em_s // small
{
static const int __n = __fn2em_s_n<1, f, k>::value;
static const int e = -__fn2em_s_e<__n, f, k>::e-1;
//typedef typename __fn2em_s_e<__n, f, k>::m m;
struct m
{
static const double __m = __fn2em_s_e<__n, f, k>::m::f_val * k;
static const double f_val = (__m < 1.0) ? 1.0 : __m;
};
};
template <bool b, int n, typename f, int k>
struct __fn2em_s_n_bool;
template <int n, typename f, int k>
struct __fn2em_s_n
{
static const double __en = __pow_kn<k, -n>::value::f_val;
static const double __h = f::f_val / __en;
static const bool __b = __h >= __en;
static const int value = __fn2em_s_n_bool<__b, n, f, k>::value;
};
template <int n, typename f, int k>
struct __fn2em_s_n_bool<true, n, f, k>
{
static const int value = n;
};
template <int n, typename f, int k>
struct __fn2em_s_n_bool<false, n, f, k>
{
static const int value = __fn2em_s_n<2*n, f, k>::value;
};
template <int n, typename f, int k>
struct __fn2em_s_e
{
static const double __f = f::f_val;
static const double __en = __pow_kn<k, -n>::value::f_val;
static const bool __s = __en > __f;
struct __h
{
static const double f_val = __s ? __f / __en : __f;
};
static const int e = __fn2em_s_e<n/2, __h, k>::e + (__s ? n : 0);
typedef typename __fn2em_s_e<n/2, __h, k>::m m;
};
template <typename f, int k>
struct __fn2em_s_e<0, f, k>
{
static const int e = 0;
typedef f m;
};
template <int n, typename f, int k>
struct __fn2em_b_n;
template <int n, typename f, int k>
struct __fn2em_b_e;
template <typename f, int k>
struct __fn2em_b
{
static const int __n = __fn2em_b_n<1, f, k>::value;
static const int e = __fn2em_b_e<__n, f, k>::e;
typedef typename __fn2em_b_e<__n, f, k>::m m;
};
template <bool b, int n, typename f, int k>
struct __fn2em_b_n_bool;
template <int n, typename f, int k>
struct __fn2em_b_n
{
static const double __en = __pow_kn<k, n>::value::f_val;
static const double __h = f::f_val / __en;
static const bool __b = __h < __en;
static const int value = __fn2em_b_n_bool<__b, n, f, k>::value;
};
template <int n, typename f, int k>
struct __fn2em_b_n_bool<true, n, f, k>
{
static const int value = n;
};
template <int n, typename f, int k>
struct __fn2em_b_n_bool<false, n, f, k>
{
static const int value = __fn2em_b_n<2*n, f, k>::value;
};
template <int n, typename f, int k>
struct __fn2em_b_e
{
static const double __f = f::f_val;
static const double __en = __pow_kn<k, n>::value::f_val;
static const bool __s = __f >= __en;
struct __h
{
static const double f_val = __s ? __f / __en : __f;
};
static const int e = __fn2em_b_e<n/2, __h, k>::e + (__s ? n : 0);
typedef typename __fn2em_b_e<n/2, __h, k>::m m;
};
template <typename f, int k>
struct __fn2em_b_e<0, f, k>
{
static const int e = 0;
typedef f m;
};
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -