std::numeric_limits<T>::infinity() returns 0 if T is an integral type. Is there a replacement for this function that I can use? I have a series of int variables (they could be int8, uint8, int32, uint32, int64, uint64) that could take on values anywhere between their minimum (inclusive) and maximum (inclusive) values.
I need a value that is smaller than all of these variables, and this value will be used to comparison purposes (I would be comparing whether this value is smaller than my series of int variables).
I know I could something like -std::numeric_limits<double>::infinity(), but if I were to compare my int variables with this value, the comparison would be done in FP precision, and I'm concerned about the performance implications of that. I would, ideally, like all the comparisons to be done with integers.
I think the smallest int value that we can have is std::numeric_limits<int64_t>::minimum(), so I think my question is essentially asking if we can get an integer value smaller than this?
You can define your own minus infinity constant that compares less than any other value.
This is less tedious with C++20's three way comparator (aka spaceship), but feasible in previous versions:
#include <compare>
struct minus_infinity_t {} constexpr minus_infinity;
auto constexpr operator<=> (minus_infinity_t, minus_infinity_t)
{ return std::weak_ordering::equivalent; }
template<class T> auto constexpr operator<=> (T, minus_infinity_t)
{ return std::weak_ordering::greater; }
template<class T> auto constexpr operator<=> (minus_infinity_t, T)
{ return std::weak_ordering::less; }
int main()
{
constexpr int n = 0;
constexpr long long k = 1;
constexpr double l = 2;
static_assert(n > minus_infinity);
static_assert(k > minus_infinity);
static_assert(l > minus_infinity);
static_assert(minus_infinity <= n);
static_assert(minus_infinity <= k);
static_assert(minus_infinity <= l);
}
Live demo
Improvement ideas:
Restrict what T can be with concepts
Define a positive infinity
Define a negative and positive zero
Related
I would like to implement a template function that compares two variables of two types (T1 and T2). These types are two random unsigned or signed integer types.
To be able to compare them correctly I need to cast both of them to a 'bigger' integer type (T3). Promotion rules for signed/unsigned comparison unfortunately always promote to the unsigned type.
So how can I find a type T3 in C++11/C++14/C++17 that covers two integer types T1 and T2, no matter which size and signedness they have?
If this isn't possible, is there an other solution to build a template based comparison function that works reliably with any integer combination?
You can split the comparison up into parts. First check if one number is negative, and the other positive. If that's the case you know what order they go in. If neither is negative (or both are), just do a normal comparison.
This can be built in a template function that'll only check for negative of signed types.
I am not sure I understand your question. Do you mean something like this:
#include <cstdint>
#include <type_traits>
template < typename P, typename Q >
auto
compare( P p, Q q ) {
using T = typename std::common_type< P, Q >::type;
T promoted_p{p};
T promoted_q{q};
if ( promoted_p < promoted_q ) {
return -1;
}
else if ( promoted_p > promoted_q ) {
return 1;
}
else {
return 0;
}
}
It will work when safe to do so, and you can add your specializations if the language is not doing what you want.
I'm relatively new to C++. I just read about the auto keyword in regards to type deduction. I've tried implementing this in a couple functions only to find that it was causing all of kinds of issues when working with math operators. I believe what was happening was that my functions started implementing integer division when I actually needed float division (variables 'i' and 'avg'). I posted the code using the auto keywords below.
Now when I explicitly declared the variables as floats, the function worked fine.
So is this an example in which using auto would not be preferred? However, I can definitely see that they would help when generating the iterators.
namespace Probability
{
/* ExpectedValueDataSet - Calculates the expected value of a data set */
template <typename T, std::size_t N>
double ExpectedValueDataSet(const std::array<T, N>& data)
{
auto i = 0;
auto avg = 0;
for(auto it = data.begin(); it != data.end(); it++)
{
i = it - data.begin() + 1;
avg = ((i-1)/i)*avg + (*it)/i;
}
std::cout << avg << " \n";
return avg;
}
};
The literal 0 is of type int.
A variable auto avg = 0; therefore has type int.
The literal 0.0 (or e.g. 3.14) has type double, which is what you want.
As a general rule, use auto for a variable declaration where
the type is explicitly specified in the initializer, or
the type is awfully verbose, like some iterator type.
But don't use it without reason. :)
If for e.g. aesthetic reasons you want to keep i as an integer, then rewrite the computation
((i-1)/i)*avg + (*it)/i
to e.g.
((i-1)*avg + *it)/i
to avoid pure integer arithmetic for (i-1)/i.
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__
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.
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.
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.)
Basically I want to restrict variables to the values 0, 1 or 2.
I have tried doing this with the following:
enum Value
{
0,
1,
2
};
Value var;
But this is a compile error because the enum values are unlabelled. It just makes the code less readable to assign names like "ZERO", "ONE" and "TWO" rather than referring to the values as 0, 1 and 2. Is there any way around this or should I just get rid of the enum and enforce the rule elsewhere?
If you want to use enum, then you need to name them. Since you're just working with integer values, and you apparently want them to actually represent integer values, your best bet is it use an int parameter, and do a quick check at the top of the method. A comment on the method specifying this constraint would be welcome.
Note that if your values actually correspond to non-numeric settings, then you should just come up with good names and use the enum
Just because you add identifiers for the values doesn't mean you have to use them... you can use Value(0), Value(2) etc. if that's more convenient, but there is a danger: enum doesn't restrict the value stored to those listed... e.g. it won't protect you against Value(3).
Inside structs/classes you can use bit fields to restrict the storage used for numbers, but even then:
- the range has to correspond to either the signed or unsigned values possible in the number of bits requested
- attempts to assign other values will result in high order bits being removed rather than any kind of compile- or run-time error
If your intention is to create a distinct type that enforces a restricted values 0 through 2, then you need a class with specialised constructor and assignment operators:
template <int MIN, int MAX>
class Bound
{
public:
explicit Bound(int n) { *this = n; }
Bound& operator=(int n)
{
if (n < MIN or n > MAX)
throw std::runtime_error("out of bounds");
n_ = n;
return *this;
}
Bound& operator+=(int n) { *this = n_ + n; }
// should "+" return int or Bound? entirely usage dependent...
Bound operator+(int n) { return Bound(n_ + n); }
// -=, -, *=, *, /=, /, %=, %, bitwise ops, pre/post ++/-- etc...
operator int() const { return n_; }
private:
int n_;
};
You are looking for the builtin int type, AFAICT
If you really want to behave like a Java programmer use ADT religiously, you can always:
template <typename ordinal=int>
struct Value
{
ordinal _val;
/*implicit*/ Value(ordinal val) : _val(val) {}
/*implicit*/ operator const ordinal&() const { return _val; }
/*implicit*/ operator ordinal&() { return _val; }
};
int main()
{
Value<> x = 3;
int y = x;
x = y;
x += 17;
x++;
return x;
}
This will return 22
Of course, it is entirely possible to make the Value<> less generic and more useful in many ways, but you didn't really tell us anything about what you want with that
I would like to create a type that is an integer value, but with a restricted range.
Attempting to create an instance of this type with a value outside the allowable range should cause a compile time error.
I have found examples that allow compile time errors to be triggered when an enumeration value outside those specified is used, but none that allow a restricted range of integers (without names).
Is this possible?
Yes but it's clunky:
// Defining as template but the main class can have the range hard-coded
template <int Min, int Max>
class limited_int {
private:
limited_int(int i) : value_(i) {}
int value_;
public:
template <int Val> // This needs to be a template for compile time errors
static limited_int make_limited() {
static_assert(Val >= Min && Val <= Max, "Bad! Bad value.");
// If you don't have static_assert upgrade your compiler or use:
//typedef char assert_in_range[Val >= Min && Val <= Max];
return Val;
}
int value() const { return value_; }
};
typedef limited_int<0, 9> digit;
int main(int argc, const char**)
{
// Error can't create directly (ctor is private)
//digit d0 = 5;
// OK
digit d1 = digit::make_limited<5>();
// Compilation error, out of range (can't create zero sized array)
//digit d2 = digit::make_limited<10>();
// Error, can't determine at compile time if argc is in range
//digit d3 = digit::make_limited<argc>();
}
Things will be much easier when C++0x is out with constexpr, static_assert and user defined literals.
Might be able to do something similar by combining macros and C++0x's static assert.
#define SET_CHECK(a,b) { static_assert(b>3 && b<7); a=b; }
A runtime integer's value can only be checked at runtime, since it only exists at runtime, but if you make a runtime check on all writing methods, you can guarantee it's contents. You can build a regular integral replacement class with given restrictions for that.
For constant integers, you could use a template to enforce such a thing.
template<bool cond, typename truetype> struct enable_if {
};
template<typename truetype> struct enable_if<true, truetype> {
typedef truetype type;
};
class RestrictedInt {
int value;
RestrictedInt(int N)
: value(N) {
}
public:
template<int N> static typename enable_if< (N > lowerbound) && (N < upperbound), RestrictedInt>::type Create() {
return RestrictedInt(N);
}
};
Attempting to create this class with a template value that isn't within the range will cause a substitution failure and a compile-time error. Of course, it will still require adornment with operators et al to replace int, and if you want to compile-time guarantee other operations, you will have to provide static functions for them (there are easier ways to guarantee compile-time arithmetic).
Well, as you noticed, there is already a form of diagnostic for enumerations.
It's generally crude: ie the checking is "loose", but could provide a crude form of check as well.
enum Range { Min = 0, Max = 31 };
You can generally assign (without complaint) any values between the minimal and maximal values defined.
You can in fact often assign a bit more (I think gcc works with powers of 2).