Fixed point implementation of bool isnan (...) function in C ++

I am implementing a fixed-point implementation in C ++, and I am trying to define a "non-number" and support the bool isnan (...) function, which returns true if the number is not a number and false otherwise.

can someone give me some ideas on how to define a "non-number" and implement the bool isnan (...) function in my fixed point math implementation.

I read about C ++ Nan, but I could not get any source or link on how to manually define and create the nan () function in order to use it in a fixed-point implementation.

can someone tell me how to proceed or give some links to continue?

thanks

UPDATE Fixed point 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__ 
+4
source share
3 answers

Typically, fixed-point math is used for embedded equipment that does not have an FPU. Basically, this hardware also does not have programs or data spaces and / or processing power.

Are you sure you need general support for NAN, INF, or something else? It may be sufficient to explicitly implement this as separate flags for operations that can generate these values.

If you use fixed point arithmetic, which you know very well, you need to know your data in order to avoid overflow or underuse on deviations or divisions. Therefore, your algorithms should be written in such a way as to avoid any special conditions in any case.

Additionally, even after using double: if you have one of your special values ​​in your algorithm, they propagate like a virus, and the result is completely useless.

As a conclusion: In my opinions, clearly implementing this in your fixed-point class, there is a significant loss of computing power because you have to add conditional conditions for each fixed-point operation. And the legend is the poison for pipelines with a deep DSP or ΞΌC processor.

+2
source

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

Depending on these factors, you can implement several different methods. The way that IEEE floating point numbers go away is that the number is encoded in a special format that allows you to set flags based on the bit pattern. In a fixed point implementation, this may not be possible. but if it is a class, you can define arithmetic operators for the class, and then set the resulting number to nan.

UPDATE

Looking at the code, it seems you are simply stuffing information into a value. Thus, the best way is to have the isnan flag in the class and set it from the corresponding mathematical operations, and then check it before performing the operations, therefore isnan propogates.

+1
source

Essentially, you should defer some value or set of values ​​to represent NaN. In each operation on your objects (for example, adding) you should check if the input value is NaN and react accordingly.

In addition, you must make sure that no normal operation leads to an unexpected NaN result. Thus, you must handle overflows and such to ensure that if the calculated result is a bitmap for NaN, you create infinity and / or an exception indication and / or any result.

It is basically this; no magic.

Generally, you do not want to use one bit as a flag, because it takes away a lot of bit combinations that can be used to represent values. IEEE 754 highlights one exponent field value (all units) to indicate infinity (if the field value is all zeros) or NaN (otherwise). Thus, only a small fraction of bit patterns are used for NaNs. (For 32-bit, there are 2 24 -2 NaNs out of 2 32 possible bit combinations, so less than 0.4% of potential values ​​are spent on NaNs.)

+1
source

Source: https://habr.com/ru/post/1479000/


All Articles