Ошибка исключения с плавающей точкой в ​​реализации с фиксированной точкой

Привет всем я реализовал заголовочный файл для выполнения артеметических операций с фиксированной точкой, который показан ниже, он выполняет операции умножения и деления.

#ifndef __fixed_point_header_h__
#define __fixed_point_header_h__
#include <boost/operators.hpp>
#include <limits>
namespace fp {
// FP The fixed point(base) type, should be an integer type
// I  Integer part bit count
// F  fractional part bit count
template<typename FP, unsigned char I, unsigned char F = std::numeric_limits<FP>::digits - I>

class fixed_point: boost::ordered_field_operators<fp::fixed_point<FP, I, F>  >
{

//As the fixed_point class needs 2 to the power of P in several parts for floating point conversions, template recursion using template metaprogramming is used to calculate 2 to the power of F at compile time itself.

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;
};

// Initializing constructor.
//! This constructor takes a value of type FP and initializes the //internal representation of fixed_point<FP, I, F> with it.
fixed_point(FP value,bool): fixed_(value){ } // initializer list

public:
typedef FP base_type; ///  fixed point base type of this fixed_point cass.
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.

//Conversion by constructors.
//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(
/// The right hand side.
fixed_point<FP, I, F> const& rhs)
//: fixed_(rhs.fixed_)
{
fixed_ = rhs.fixed_;
}
// Copy assignment operator.
fp::fixed_point<FP, I, F> & operator =(fp::fixed_point<FP, I, F> const& rhs)
{
fp::fixed_point<FP, I, F> temp(rhs);
swap(temp);
return *this;  //return by reference
}
/// Exchanges the elements of two fixed_point objects.
void swap(
/// The right hand side.
fp::fixed_point<FP, I, F> & rhs)
{
std::swap(fixed_, rhs.fixed_);
}
/// Multiplication.
fp::fixed_point<FP, I, F> & operator *=(
/// Factor for mutliplication.
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 /=(
/// Divisor for division.
fp::fixed_point<FP, I, F> const& divisor)
{

fixed_ = ( (fixed_)<< F  / divisor.fixed_  )+
( ( fixed_ / (divisor.fixed_ & (power2<F>::value-1) ) )<< F   );
return *this;   //return A reference to this object.
}
private:
/// The value in fixed point format.
FP fixed_;
};

} // namespace fp
#endif // __fixed_point_header__

например, для умножения я повысил тип результирующей фиксированной точки (когда умножаются два 8-битных числа, получается 16-битный результат). это работает нормально.

но когда я делаю деление со следующим тестовым файлом
test.cpp

#include <stdio.h>
#include <fixed_point_header.h>
int main()
{
fp::fixed_point<int, 15> fp1 = 3.0; // 011 0000 0000 0000 0000
fp::fixed_point<int, 15> fp2 = 3.0; // 100 0000 0000 0000 0000
fp::fixed_point<int, 15> fp3;

fp3 = fp1/fp2;
printf("divided value ==%f\n", (float)fp3 );
}

я всегда получаю ошибку исключения с плавающей запятой, некоторые могут проверить это и посмотреть, что происходит.

0

Решение

Конечно, это потенциально приводит к делению на ноль:

   fixed_ = ( (fixed_)<< F  / divisor.fixed_  )+
( ( fixed_ / (divisor.fixed_ & (power2<F>::value-1) ) )<< F   );
return *this;   //return A reference to this object.

Если divisor.fixed_ & (power2<F>::value-1) равен нулю, то вы получите деление на ноль.

Я также не уверен, что это правильно, но я оставлю это на ваше усмотрение, чтобы понять это, поскольку я на самом деле не рассматривал, как вы делите «фиксированную точку» деления.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]