4

i am doing fixed point implementation in c++ and i am trying to define “not-a-number” and support a function bool isnan( … ) which returns true if the number is not-a-number and false otherwise.

can someone one give me some ideas of how to define “not-a-number” and implement a function bool isnan( … ) in my fixed point math implemenation.

i have read about C++ Nan, but i couldnt get any source or reference for how to manually define and create function nan() to use it in fixed point implemenation.

can some one tell me how to proceed or give some references to proceed?

Thank you

UPDATE Fixedpoint header

#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__
Dev
  • 153
  • 1
  • 1
  • 6
  • is my question clear/ understandable? – Dev May 03 '13 at 14:42
  • 1
    Names that contain two consecutive underscores (`__fixed_point_header_h__`) and names that start with an underscore followed by a capital letter are reserved to the implementation. don't use them. – Pete Becker May 03 '13 at 15:12
  • @PeteBecker Okay thank you, did you find any ideas to implement a bool function isnan() in the fixedpoint class mentioned above. – Dev May 03 '13 at 15:15
  • 1. add a flag { bool isNaN; } or 2. { -0 == NaN } (sign and zero at the same time) but in both cases you need to handle it in all arithmetic/logic subfunctions like +,-,++,--,*,/,%,<,>,<=,>=,==,!=,^,|,&,^^,||,&&,... – Spektre Oct 14 '13 at 09:52
  • @Spektre: He uses the first template type as the storage, which is presumably a integral type, which _usually_ doesn't have a -0 representation. He'd have to choose a specific bitpattern – Mooing Duck May 15 '15 at 02:04

3 Answers3

3

usually fixedpoint math is used on embedded hardware that has no FPU. Mostly this hardware also lacks of Programm or Data Space or/and processing power.

Are you sure that you require a generic support of NAN, INF, or what ever? May be it is sufficient to explicitly implement this on as separate Flags on the operations that can produce theese values.

THen you use fixed point arithmetic you extremely good have to know your data to avoid overflows or underflows on mutliplications or divisions. So your algorithms have to be written in a way that avoids theese special conditions anyway.

Additional to this even then using double: once you have one of theese special values in your algorithm they spread like a virus and the result is quite useless.

As conlusion: In My Opinions explicitly implementing this in your fixedpoint class is a significant waste of processing power, because you have to add conditionals to every fixpoint operation. And conditionals are poison to the deep cpu pipelines of DSPs or µC.

vlad_tepesch
  • 6,681
  • 1
  • 38
  • 80
1

Could you give us an example of what you mean by fixed point? Is it implemented as a class? Is it fixed number of bytes, or do you support 8, 16, 32, 64bit numbers? How do you represent negative values?

Depending on these factors you can implement a few possibe different ways. The way the IEEE floating point numbers get away with it, is because the number are encoded in a special format allowing flags to be set based on the bit pattern. In a fixed point implementation that might not be possible. but if its a class you could define the arithmetic operators for the class and then set the resultant number to be nan.

UPDATE

Looking at the code it seems you are just stuffing the information in the value. So the best way may be to have an isnan flag in the class, and set it from the appropriate math operations, and then check for it before you perform the operations so the isnan propogates.

Tim Felty
  • 152
  • 12
  • could you please see my updated question where i provided my full fixedpoint class? – Dev May 03 '13 at 14:52
1

Essentially, you must set aside some value or set of values to represent a NaN. In every operation on your objects (e.g., addition), you must test whether an input value is a NaN and respond accordingly.

Additionally, you must make sure no normal operation produces a NaN result inadvertently. So you have to handle overflows and such to ensure that, if a calculated result would be a bit pattern for a NaN, you produce an infinity and/or an exception indication and/or whatever result is desired.

That is basically it; there is no magic.

Generally, you would not want to use a single bit as a flag, because that wastes many bit combinations that could be used to represent values. IEEE 754 sets aside one value of the exponent field (all ones) to indicate infinity (if the significand field is all zeroes) or NaN (otherwise). That way, only a small portion of the bit combinations are used for NaNs. (For 32-bit, there are 224-2 NaNs out of 232 possible bit combinations, so less than .4% of the potential values are expended on NaNs.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312