с плавающей точкой — реализация функции bool isnan (…) с фиксированной точкой в ​​переполнении стека

я делаю реализацию с фиксированной запятой в c ++, и я пытаюсь определить «not-a-number» и поддерживать функцию 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__

4

Решение

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

Вы уверены, что вам нужна общая поддержка NAN, INF или чего-либо еще?
Может быть, достаточно явно реализовать это как отдельные флаги для операций, которые могут давать эти значения.

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

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

В качестве заключения: в «Моих мнениях» явная реализация этого в вашем классе с фиксированной точкой является значительной тратой вычислительной мощности, потому что вы должны добавлять условные выражения к каждой операции с фиксированной точкой. И условные обозначения являются ядом для глубоких процессоров ЦПС или микроконтроллеров.

2

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

Не могли бы вы дать нам пример того, что вы подразумеваете под фиксированной точкой? Это реализовано как класс? Это фиксированное число байтов, или вы поддерживаете 8, 16, 32, 64-битные числа? Как вы представляете отрицательные значения?

В зависимости от этих факторов вы можете реализовать несколько различных способов. То, как числа с плавающей запятой IEEE обходятся без него, заключается в том, что числа кодируются в специальном формате, позволяющем устанавливать флаги на основе битовой комбинации. В реализации с фиксированной точкой это может быть невозможно. но если это класс, вы можете определить арифметические операторы для класса и затем установить результирующее число равным nan.

ОБНОВИТЬ

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

1

По сути, вы должны выделить какое-то значение или набор значений для представления NaN. В каждой операции над вашими объектами (например, добавление) вы должны проверить, является ли входное значение NaN, и ответить соответствующим образом.

Кроме того, вы должны убедиться, что никакая нормальная работа не приводит к непреднамеренному результату NaN. Таким образом, вы должны обрабатывать переполнения и тому подобное, чтобы гарантировать, что, если вычисляемый результат будет битовым шаблоном для NaN, вы создадите бесконечность и / или индикацию исключения и / или любой желаемый результат.

Это в основном это; нет волшебства

Как правило, вы не хотите использовать один бит в качестве флага, потому что это тратит много битовых комбинаций, которые могут быть использованы для представления значений. IEEE 754 выделяет одно значение поля экспоненты (все единицы), чтобы указать бесконечность (если в значимом поле все нули) или NaN (в противном случае). Таким образом, только небольшая часть битовых комбинаций используется для NaN. (Для 32-битных есть 224-2 NaNs из 232 возможные комбинации битов, поэтому на NaN расходуется менее 0,4% потенциальных значений.)

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