⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fn.hpp

📁 浮点数基本运算 浮点数的基本运算主要有四则运算、符号处理、大小比较
💻 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 + -