The numeric_limits traits is supposed to be a general way of obtaining various type infomation, to be able to do things like
template<typename T>
T min(const std::vector<T>& vect)
{
T val = std::numeric_limits<T>::min();
for(int i=0 ; i<vect.size() ; i++)
val = max(T, vect[i]);
return val;
}
The problem is that (at least using MS Visual Studio 2008) numeric_limits<int>::min() returns the smallest negative number, while numeric_limits<double>::min() returns the smallest positive number!
Anyone knows the rationalie behind this design? Is there a better (recommended?) way of using numeric_limits? In my specific function above, I could of course initialize T to vect[0], but that is not the answer I am looking for..
See also (floating-point-specific) discussion
here
You can use Boost libraries. The library Numeric Conversions provides a class called bounds that can be used consistently.
See the documentation here.
This is an old thread, but there is an updated answer:
C++11 added a lowest() function to std::numeric_limits (See here)
So you can now call std::numeric_limits<double>::lowest() to get the lowest representable negative value.
The behaviour of min() isn't all that strange, it returns FLT_MIN, DBL_MIN or INT_MIN (or their respective values), depending on the type you specialize with. So your question should be why FLT_MIN and DBL_MIN are defined differently from INT_MIN.
Unfortunately, I don't know the answer to that latter question.
My suspicion is that it was defined that way for practical purposes. For integer numbers, you're usually concerned with overflow/underflow, where the minimum and maximum value become of interest.
For floating point numbers, there exists a different kind of underflow in that a calculation could result in a value that's larger than zero, but smaller than the smallest representable decimal for that floating point type. Knowing that smallest representable floating point value allows you to work around the issue. See also the Wikipedia article on subnormal/denormal numbers.
A workaround would be
double val = -std::numeric_limits<double>::max();
Of course, this doesn't explain the strange behaviour of numerics_limits::min() which could be a result of the fact that there are different min/max borders for integers (min = -2^n, max = 2^n-1) but not for doubles.
I'm not sure of the rationale but it is expected behaviour. Well, in the sense that is how Josuttis (and, presumably the standard) describes it!
min(): "Miniumum finite value (minimum
normalized value for floating-point
types with denormalization)."
As best I can tell if the type is not an integer (numeric_limits<>::is_integer) and has denormalization (numeric_limits<>::has_denorm) min() will return the smallest representable value by that type. Otherwise it will return the smallest value - which may be negative.
For a more consistent interface check out the Boost numeric/conversion library. Specifically the bounds traits class. Here's a snippet:
cout << "lowest float:" << boost::numeric::bounds<float>::lowest();
cout << "lowest int: " << boost::numeric::bounds<int>::lowest();
You may also find the boost::integer library useful. It brings some of C99's integer support (like int_least16_t) to C++ and can help select the best sized type for you particular need. An example:
boost::uint_t<20>::fast fastest20bits; // fastest unsigned integer that
// can hold at least 20 bits.
boost::int_max_value_t<100000>::least // smallest integer that can store
// the value 100000.
I often find that when I need one of boost::numeric/conversion or boost::integer I need them both.
numeric_limits<int>::min returned the lowest negative number, all floating point number types, return the smallest positive number when I tried it with Sun CC & g++.
I guess this is because 'smallest' and 'minimum' mean different things with floating point numbers. It is a bit odd though.
Both Sun CC and g++ produce the same result :
short:min: -32768 max: 32767
int:min: -2147483648 max: 2147483647
unsigned int:min: 0 max: 4294967295
long:min: -2147483648 max: 2147483647
float:min: 1.17549e-38 max:
3.40282e+38
double:min: 2.22507e-308 max:
1.79769e+308
long double:min: 3.3621e-4932 max:
1.18973e+4932
unsigned short:min: 0 max: 65535
unsigned int:min: 0 max: 4294967295
unsigned long:min: 0 max: 429496729
template<typename T>
void showMinMax()
{
cout << "min: " << numeric_limits<T>::min() << endl;
cout << "max: " << numeric_limits<T>::max() << endl;
cout << endl;
}
int main()
{
cout << "short:";
showMinMax<short>()
...etc...etc..
The definition of the smallest value for an empty vector can be argued. If the vector is empty then there is no smallest element.
Prefer to use std::min_element instead:
int main()
{
std::vector<int> v;
std::generate_n(std::back_inserter(v), 1000, std::rand);
std::vector<int>::iterator it = std::min_element(v.begin(), v.end());
if (it == v.end())
{
std::cout << "There is no smallest element" << std::endl;
}
else
{
std::cout << "The smallest element is " << *it << std::endl;
}
}
Related
I am not an advanced C++ programmer. But I have been using C++ for a long time now. So, I love playing with it. Lately I was thinking about ways to maximize a variable programmatically. So I tried Bitwise Operators to fill a variable with 1's. Then there's signed and unsigned issue. My knowledge of memory representation is not very well. However, I ended up writing the following code which is working for both signed and unsigned short, int and long (although int and long are basically the same). Unfortunately, for long long, the program is failing.
So, what is going on behind the scenes for long long? How is it represented in memory? Besides, Is there any better way to do achieve the same thing in C++?
#include <bits/stdc++.h>
using namespace std;
template<typename T>
void Maximize(T &val, bool isSigned)
{
int length = sizeof(T) * 8;
cout << "\nlength = " << length << "\n";
// clearing
for(int i=0; i<length; i++)
{
val &= 0 << i;
}
if(isSigned)
{
length--;
}
val = 1 << 0;
for(int i=1; i<length; i++)
{
val |= 1 << i;
cout << "\ni = " << i << "\nval = " << val << "\n";
}
}
int main()
{
long long i;
Maximize(i, true);
cout << "\n\nsizeof(i) = " << sizeof(i) << " bytes" << "\n";
cout << "i = " << i << "\n";
return 0;
}
The basic issue with your code is in the statements
val &= 0 << i;
and
val |= 1 << i;
in the case that val is longer than an int.
In the first expression, 0 << i is (most likely) always 0, regardless of i (technically, it suffers from the same undefined behaviour described below, but you will not likely encounter the problem.) So there was no need for the loop at all; all of the statements do the same thing, which is to zero out val. Of course, val = 0; would have been a simpler way of writing that.
The issue 1 << i is that the constant literal 1 is an int (because it is small enough to be represented as an int, and int is the narrowest representation used for integeral constants). Since 1 is an int, so is 1 << i. If i is greater than or equal to the number of value bits in an int, that expression has undefined behaviour, so in theory the result could be anything. In practice, however, the result is likely to be the same width as an int, so only the low-order bits will be affected.
It is certainly possible to convert the 1 to type T (although in general, you might need to be cautious about corner cases when T is signed), but it is easier to convert the 1 to an unsigned type at least as wide as Tby using the maximum-width unsigned integer type defined in cstdint, uintmax_t:
val |= std::uintmax_t(1) << i;
In real-world code, it is common to see the assumption that the widest integer type is long long:
val |= 1ULL << i;
which will work fine if the program never attempts to instantiate the template with a extended integer type.
Of course, this is not the way to find the largest value for an integer type. The correct solution is to #include <limits> and then use the appropriate specialization of std::numeric_limits<T>::max()
C++ allows only one representation for positive (and unsigned) integers, and three possible representations for negative signed integers. Positive and unsigned integers are simply represented as a sequence of bits in binary notation. There may be padding bits as well, and signed integers have a single sign bit which must be 0 in the case of positive integers, so there is no guarantee that there are 8*sizeof(T) useful bits in the representation, even if the number of bits in a byte is known to be 8 (and, in theory, it could be larger). [Note 1]
The sign bit for negative signed integers is always 1, but there are three different formats for the value bits. The most common is "two's complement", where the value bits interpreted as a positive number would be exactly 2k more than the actual value of the number, where k is the number of value bits. (This is equivalent to specifying a weight of 2-k to the sign bits, which is why it is called 2s complement.)
Another alternative is "one's complement", in which the value bits are all inverted individually. This differs by exactly one from two's-complement representation.
The third allowable alternative is "sign-magnitude", in which the value bits are precisely the absolute value of the negative number. This representation is frequently used for floating point values, but only rarely used in integer values.
Both sign-magnitude and one's complement suffer from the disadvantage that there is a bit pattern which represents "negative 0". On the other hand, two's complement representation has the feature that the magnitude of the most negative representable value is one larger than the magnitude of the most positive representable value, with the result that both -x and x/-1 can overflow, leading to undefined behaviour.
Notes
I believe that it is theoretically possible for padding to be inserted between the value bits and the sign bits, but I certainly do not know of any real-world implementation with that feature. However, the fact that attempting to shift a 1 into the sign bit position is undefined behaviour makes it incorrect to assume that the sign bit is contiguous with the value bits.
I was thinking about ways to maximize a variable programmatically.
You are trying to reinvent the wheel. C++ STL already has this functionality: std::numeric_limits::max()
// x any kind of numeric type: any integer or any floating point value
x = std::numeric_limits<decltype(x)>::max();
This is also better since you will not relay on undefined behavior.
As harold commented, the solution is to use T(1) << i instead of 1 << i. Also as Some programmer dude mentioned, long long is represented as consecutive bytes (typically 8 bytes) with sign bit at the MSB if it is signed.
As in this question is said, there is some differences between negative and positive zero in floating point numbers. I know it's because of some important reasons. what I want to know is a short code to avoid negative zero in output.
for example in the following code:
cout << fixed << setprecision(3);
cout << (-0.0001) << endl;
"-0.000" is printed. but I want "0.000".
Note all other negative numbers (e.g. -0.001) should still be printed with the minus sign preceding them, so simply * -1 will not work.
Try depending on your precision.
cout << ((abs(ans) < 0.0005)? 0.000: ans) << endl;
How about:
cout << (value == 0.0 ? abs(value) : value) << endl;
If you care about arbitrary precision, as opposed to just a fixed one at 3, you'll need a small bit of work. Basically, you'll have to do a pre-check before the cout to see if the number will get formatted in a way you don't like.
You need to find the order of magnitude of the number to see if it the imprecise digits will be lost, leaving only the sign bit.
You can do this using the base 10 logarithm of the absolute value of the number. If negative of result is greater than the precision you have set, the number will show in a way you don't want.
log10 of 0.0001 is -4.
negative of (-4) is 4.
4 > 3 (the arbitrary precision)
Thus the value will show up unhappily.
In very bad pseudocode:
float iHateNegativeZeros(float theFloat, int precision)
{
if((theFloat < 0.0f) &&
(-log10(abs(theFloat)) > precision))
{
return -theFloat;
}
else
{
return theFloat;
}
}
I have a function with two arguments, a vector whose elements are being tested, and a bool variable that we enter as true or false. If we enter true then it is supposed to isolate and place all the elements whose sum of digits is an even number to a new vector (in the same order they came) and return that vector. With false it's the opposite, odd numbers. And you can only use pretty much the things I have already used here, nothing else.
This is how it looks.
std::vector<int> IzdvojiElemente(std::vector<int> v, bool flag){
std::vector<int> n;
for(int i(0); i<v.size();i++){
int suma(0);
int temp(v[i]);
if(temp<0) temp*=-1;
while(temp>0){
suma+=temp%10;
temp/=10;
}
if(flag && suma%2==0) n.push_back(v[i]);
if(!flag && suma%2!=0) n.push_back(v[i]);
}
return n;
}
And this is one of the main functions for which it doesn't work:
std::vector<int> v1 {1,std::numeric_limits<int>::min(),2, std::numeric_limits<int>::max(),5};
std::vector<int> v2;
v2 = IzdvojiElemente(v1, false);
for(int i=0; i < v2.size(); i++)
std::cout << v2[i] << " ";
This is what I was supposed to get (as output):
1 -2147483648 5
This is what I got:
1 5
For some reason it either ignores the numeric limits, or doesn't but sorts them with the wrong vector. And I don't know why. In any other cases it works as it should. And maybe it's overflow, but I can't see where.
Yes, this is overflow. Note that in 2's complement representation of signed integers (the common representation on mainstream platforms), the representable range is not symmetric: when the lowest representable number is -2147483648, then the highest representable one is 2147483647.
-2147483648 * -1 is therefore signed integer overflow and Undefined Behaviour, meaning the program is wrong and anything can happen.
If you're supposed to handle std::numeric_limits<int>::min() correctly regardless of internal representation, you will have to deal with negative numbers differently (such as computing the digit sum in negative and then just sign-reverse the computed sum).
I'm trying to find the minimum value (closest to zero) that I can store in a single precission floating point number. Using the <limits> header I can get the value, but if I make it much smaller, the float can still hold it and it gives the right result. Here is a test program, compiled with g++ 5.3.0.
#include <limits>
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
float a = numeric_limits<float>::max();
float b = numeric_limits<float>::min();
a = a*2;
b = b/pow(2,23);
cout << a << endl;
cout << b << endl;
}
As I expected, "a" gives infinity, but "b" keeps holding the good result even after dividing the minimum value by 2^23, after that it gives 0.
The value that gives numeric_limits<float>::min() is 2^(-126) which I belive is the correct answer, but why is the float on my progam holding such small numbers?
std::numeric_limits::min for floating-point types gives the smallest non-zero value that can be represented without loss of precision. std::numeric_limits::lowest gives the smallest representable value. With IEEE representations that's a subnormal value (previously called denormalized).
From wikipedia https://en.wikipedia.org/wiki/Single-precision_floating-point_format:
The minimum positive normal value is 2^−126 ≈ 1.18 × 10^−38 and the
minimum positive (denormal) value is 2^−149 ≈ 1.4 × 10^−45.
So, for
cout << (float)pow(2,-149)
<< "-->" << (float)pow(2,-150)
<< "-->" << (float)pow(2,-151) << endl;
I'm getting:
1.4013e-45-->0-->0
I'm trying to find the minimum value (closest to zero) that I can
store in a single precission floating point number
0 is the closest value to 0 that you can store in any precision float. In fact, you can store it two ways, as there is a positive and negative 0.
I have a program where I need to set a variable to the lowest representable (non infinite) double-precision floating point number in C++. How am I able to set a variable to the lowest double-precision floating point value?
I tried using std::numeric_limits. I am not using C++11 so I am unable to try to use the lowest() function. I tried to use max(), but when I tried it, it returned infinity. I also tried subtracting a value from max() in the hope that I would then get a representable number.
double max_value = std::numeric_limits<double>::max();
cout << "Test 1: " << max_value << endl;
max_value = max_value - 1;
cout << "Test 2: " << max_value << endl;
double low_value = - std::numeric_limits<double>::max();
cout << "Test 3: " << low_value << endl;
cout << "Test 4: " << low_value + 1 << endl;
Output:
Test 1: inf
Test 2: inf
Test 3: -inf
Test 4: -inf
How can I set low_value in the example above to the lowest representable double?
Once you have -inf (you got it), you can get the lowest finite value with the nextafter function on (-inf,0).
EDIT: Depending on the context, this may be better than -DBL_MAX in case DBL_MAX is represented in decimal (thus in an inexact way). However the C standard requires that floating constants be evaluated in the default rounding mode (i.e. to nearest). In the particular case of GCC, DBL_MAX is a long double value cast to double; however the long double value seems to have enough digits so that, once converted from decimal to long double, the value is exactly representable in as double, so that the cast is exact and the active rounding mode doesn't affect it. As you can see, this is rather tricky, and one may want to check on various platforms that it is correct under any context. In a similar way, I have serious doubts on the correctness of the definition DBL_EPSILON by GCC on PowerPC (where the long double type is implemented as a double-double arithmetic) since there are many long double values extremely close to a power of two.
The standard library <cfloat>/<float.h> provides macros defining floating point implementation parameters.
The question is somewhat ambiguous - it is not clear whether you mean the smallest magnitude representable non-zero value (which would be DBL_MIN) or the lowest representable value (given by -DBL_MAX). Either way - take your pick as necessary.
It turned out that there was a bug in the iostream that I was using to print the values. I switched to using cstdio instead of iostream. The values were then printed as expected.
double low_value = - std::numeric_limits<double>::max();
cout <<"cout: " << low_value << endl;
printf("printf: %f\n",low_value);
Output:
cout: inf
printf: 179769...