【问题标题】:fixedpoint implementation of function bool isnan( … ) in C++C++ 中函数 bool isnan( ... ) 的定点实现
【发布时间】:2013-04-27 23:59:15
【问题描述】:

我正在用 C++ 进行定点实现,我正在尝试定义“非数字”并支持一个函数 bool isnan( ... ),如果数字不是数字则返回 true,否则返回 false。

谁能给我一些关于如何定义“非数字”并在我的定点数学实现中实现函数 bool isnan( ... ) 的想法。

我已经阅读了有关 C++ Nan 的信息,但我无法获得有关如何手动定义和创建函数 nan() 以在定点实现中使用它的任何来源或参考。

有人可以告诉我如何继续或提供一些参考以继续吗?

谢谢

更新定点标头

#ifndef __fixed_point_header_h__
#define __fixed_point_header_h__
#include <boost/operators.hpp>
#include <boost/assert.hpp>
#endif
namespace fp {
    template<typename FP, unsigned char I, unsigned char F>
    class fixed_point: boost::ordered_field_operators<fp::fixed_point<FP, I, F>  >
    { 
    //compute the power of 2 at compile time by template recursion
    template<int P,typename T = void> 
    struct power2
    {
        static const long long value = 2 * power2<P-1,T>::value;
    };

    template <typename P>
    struct power2<0, P>
    {
        static const long long value = 1;
    };
    fixed_point(FP value,bool): fixed_(value){ } // initializer list
    public:
    typedef FP base_type; ///  fixed point base type of this fixed_point class.
    static const unsigned char integer_bit_count = I; ///  integer part bit count.
    static const unsigned char fractional_bit_count = F; /// fractional part bit count.
    fixed_point(){ } /// Default constructor.

    //Integer to Fixed point
    template<typename T> fixed_point(T value) : fixed_((FP)value << F)
   {
    BOOST_CONCEPT_ASSERT((boost::Integer<T>)); 
    }
    //floating point to fixed point
    fixed_point(float value) :fixed_((FP)(value * power2<F>::value)){ }
    fixed_point(double value) : fixed_((FP)(value * power2<F>::value))  { }
    fixed_point(long double value) : fixed_((FP)(value * power2<F>::value)) { }
    /// Copy constructor,explicit definition
    fixed_point(fixed_point<FP, I, F> const& rhs): fixed_(rhs.fixed_)
    { }

    // copy-and-swap idiom.

    fp::fixed_point<FP, I, F> & operator =(fp::fixed_point<FP, I, F> const& rhs)
    {
    fp::fixed_point<FP, I, F> temp(rhs); // First, make a copy of the right-hand side
    swap(temp); //swapping the copied(old) data the new data.
    return *this;  //return by reference
    }
    /// Exchanges the elements of two fixed_point objects.
    void swap(fp::fixed_point<FP, I, F> & rhs)
    {
        std::swap(fixed_, rhs.fixed_);
    }
    bool operator <(
        /// Right hand side.
        fp::fixed_point<FP, I, F> const& rhs) const
    {
        return fixed_ < rhs.fixed_;  //return by value
    }

    bool operator ==(
        /// Right hand side.
        fp::fixed_point<FP, I, F> const& rhs) const
    {
        return fixed_ == rhs.fixed_; //return by value
    }
    // Addition.
    fp::fixed_point<FP, I, F> & operator +=(fp::fixed_point<FP, I, F> const& summation)
    {
        fixed_ += summation.fixed_;
        return *this; //! /return A reference to this object.
    }
    /// Subtraction.
    fp::fixed_point<FP, I, F> & operator -=(fp::fixed_point<FP, I, F> const& subtraction)
    {
        fixed_ -= subtraction.fixed_;
        return *this;  // return A reference to this object.
    }
    // Multiplication.
    fp::fixed_point<FP, I, F> & operator *=(fp::fixed_point<FP, I, F> const& factor)
    {
    fixed_ = ( fixed_ * (factor.fixed_ >> F) ) +
        ( ( fixed_ * (factor.fixed_ & (power2<F>::value-1) ) ) >> F );
        return *this;   //return A reference to this object.
    }
    /// Division.
    fp::fixed_point<FP, I, F> & operator /=(fp::fixed_point<FP, I, F> const& divisor)
    {
     fp::fixed_point<FP, I, F> fp_z=1;
     fp_z.fixed_ = ( (fp_z.fixed_) << (F-2) ) / ( divisor.fixed_ >> (2) );
    *this *= fp_z;
     return *this;   //return A reference to this object
    }
private:
    /// The value in fixed point format.
    FP fixed_;
 };

} // namespace fmpl

#endif

#endif // __fixed_point_header__

【问题讨论】:

  • 我的问题清楚/可以理解吗?
  • 包含两个连续下划线 (__fixed_point_header_h__) 的名称和以下划线后跟大写字母的名称保留给实现。不要使用它们。
  • @PeteBecker 好的,谢谢,你有没有找到在上面提到的定点类中实现布尔函数 isnan() 的任何想法。
  • 1.添加一个标志 { bool isNaN; } 或 2. { -0 == NaN } (同时有符号和零),但在这两种情况下,您都需要在所有算术/逻辑子函数中处理它,例如 +、-、++、--、*、/、 %,,=,==,!=,^,|,&,^^,||,&&,...
  • @Spektre:他使用第一个模板类型作为存储,大概是整数类型,通常没有-0表示。他必须选择一个特定的位模式

标签: c++ floating-point nan fixed-point


【解决方案1】:

通常在没有 FPU 的嵌入式硬件上使用定点数学。 大多数情况下,这种硬件也缺乏程序或数据空间或/和处理能力。

您确定需要对 NAN、INF 或其他任何类型的通用支持吗? 在可以产生这些值的操作上将其显式实现为单独的标志可能就足够了。

然后您使用定点算术,您必须非常了解您的数据,以避免在乘法或除法时出现溢出或下溢。所以你的算法必须以一种避免这些特殊情况的方式编写。

除此之外,即使使用 double:一旦你的算法中有这些特殊值之一,它们就会像病毒一样传播,结果毫无用处。

作为结论:在我的意见中,在您的定点类中显式实现此功能会严重浪费处理能力,因为您必须为每个定点操作添加条件。条件语句对 DSP 或 µC 的深层 CPU 流水线有毒。

【讨论】:

    【解决方案2】:

    您能给我们举个例子来说明您所说的定点是什么意思吗?它是作为一个类实现的吗?是固定字节数,还是支持 8、16、32、64 位数字?你如何表示负值?

    根据这些因素,您可以采用几种可能的不同方式。 IEEE 浮点数摆脱它的方式是因为数字以特殊格式编码,允许根据位模式设置标志。在可能不可能的定点实现中。但如果它是一个类,您可以为该类定义算术运算符,然后将结果数设置为 nan。

    更新

    查看代码,您似乎只是在值中填充信息。所以最好的方法可能是在类中有一个 isnan 标志,并通过适当的数学运算设置它,然后在执行操作之前检查它,以便 isnan 传播。

    【讨论】:

    • 能否请您查看我在哪里提供了完整的定点类的更新问题?
    【解决方案3】:

    本质上,您必须留出一些值或一组值来表示 NaN。在对对象的每个操作(例如加法)中,您必须测试输入值是否为 NaN 并做出相应的响应。

    此外,您必须确保正常操作不会无意中产生 NaN 结果。因此,您必须处理溢出等问题,以确保如果计算结果是 NaN 的位模式,您会产生无穷大和/或异常指示和/或任何所需的结果。

    基本上就是这样;没有魔法。

    通常,您不希望使用单个位作为标志,因为这会浪费许多可用于表示值的位组合。 IEEE 754 保留指数字段的一个值(全为 1)以指示无穷大(如果有效数字字段全为零)或 NaN(否则)。这样,只有一小部分位组合用于 NaN。 (对于 32 位,232 个可能的位组合中有 224-2 个 NaN,因此不到 0.4% 的潜在值用于 NaN。 )

    【讨论】:

      猜你喜欢
      • 2013-05-07
      • 2014-07-27
      • 2013-02-17
      • 2021-11-21
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      • 2013-04-04
      相关资源
      最近更新 更多