Should C++ std::uniform_real_distribution<double> only generate positive numbers? - c++

I was trying to generate some random doubles in C++ (MSVC, though that isn't too important to me—I just didn't have another compiler to test) and I noticed that my quick program never generated negative numbers:
#include <iostream>
#include <random>
#include <ctime>
int main() {
std::mt19937 generator(clock());
std::uniform_real_distribution<double>
rand_dbl(std::numeric_limits<double>::min(),
std::numeric_limits<double>::max());
std::cout << "Double Limits: (" << std::numeric_limits<double>::min()
<< "," << std::numeric_limits<double>::max() << ")"
<< std::endl << std::endl;
int total_neg = 0;
for (int i=0; i<100; i++) {
double d = rand_dbl(generator);
if (d<0) total_neg++;
std::cout << d << " ";
}
std::cout << std::endl << std::endl
<< "Total negative random double is: " << total_neg << std::endl;
return 0;
}
No matter how many numbers I have it generate, it never generates a negative one. I understand why most of the numbers generated are in the 10307 - 10308 range (which isn't exactly what I wanted), but not why the numbers are always positive. I tried a few different generators (default, mt19937, minstd_rand0) without any difference in this aspect.
Can anyone describe why this is the case?

You set it up that way with the limits that you provided. std::numeric_limits<double>::min() gives the smallest positive double, and you used that as the lower bound on the distribution.

std::numeric_limits<double>::min()
Will return DBL_MIN which is the smalles value closest to 0 a double can hold. If you want the largest negative value then you need to use
std::numeric_limits<double>::lowest()
Which will return -DBL_MAX which is the largest negative value a double can hold.

From cppreference:
For floating-point types with denormalization, min returns the minimum positive normalized value.
(emphasis mine)
So it's pretty normal you only get positive values.
Could you tell what is displayed by those lines?
std::cout << "Double Limits: (" << std::numeric_limits<double>::min()
<< "," << std::numeric_limits<double>::max() << ")"
<< std::endl << std::endl;

Related

std::cout with floating number

I'm using visual studio 2015 to print two floating numbers:
double d1 = 1.5;
double d2 = 123456.789;
std::cout << "value1: " << d1 << std::endl;
std::cout << "value2: " << d2 << std::endl;
std::cout << "maximum number of significant decimal digits (value1): " << -std::log10(std::nextafter(d1, std::numeric_limits<double>::max()) - d1) << std::endl;
std::cout << "maximum number of significant decimal digits (value2): " << -std::log10(std::nextafter(d2, std::numeric_limits<double>::max()) - d2) << std::endl;
This prints the following:
value1: 1.5
value2: 123457
maximum number of significant decimal digits (value1): 15.6536
maximum number of significant decimal digits (value2): 10.8371
Why 123457 is printed out for the value 123456.789? Does ANSI C++ specification allow to display anything for floating numbers when std::cout is used without std::setprecision()?
The rounding off happens because of the C++ standard which can be seen by writing
std::cout<<std::cout.precision();
The output screen will show 6 which tells that the default number of significant digits which will be printed by the std::cout statement is 6. That is why it automatically rounds off the floating number to 6 digits.
What you have have pointed out is actually one of those many things that the standardization committee should consider regarding the standard iostream in C++. Such things work well when you write :-
printf ("%f\n", d2);
But not with std::cout where you need to use std::setprecision because it's formatting is similar to the use of %g instead of %f in printf. So you need to write :-
std::cout << std::setprecision(10) << "value2: " << d2 << std::endl;
But if you dont like this method & are using C++11 (& onwards) then you can also write :-
std::cout << "value2: " << std::to_string(d2) << std::endl;
This will give you the same result as printf ("%f\n", d2);.
A much better method is to cancel the rounding that occurs in std::cout by using std::fixed :-
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::fixed;
double d = 123456.789;
std::cout << d;
return 0;
}
Output :-
123456.789000
So I guess your problem is solved !!
I think the problem here is that the C++ standard is not written to be easy to read, it is written to be precise and not repeat itself. So if you look up the operator<<(double), it doesn't say anything other than "it uses num_put - because that is how the cout << some_float_value is implemented.
The default behaviour is what print("%g", value); does [table 88 in n3337 version of the C++ standard explains what the equivalence of printf and c++ formatting]. So if you want to do %.16g you need to change the precision by calling setprecision(16).

My small std::unique example not working

I'm trying to use cxx-11's std::unique() to find
the unique elements in an array:
#include <iostream>
#include <algorithm>
#include <vector>
#include <typeinfo>
int main(){
const int n=11;
double x[n],a3[n],a1[n];
x[0]=-0.717778;
x[1]=-0.496843;
x[2]=-0.429063;
x[3]=-0.3596;
x[4]=-0.205607;
x[5]=0.0730536;
x[6]=0.138018;
x[7]=0.585526;
x[8]=2.40104;
x[9]=3.75268;
x[10]=4.55704;
a3[0]=0.790832;
a3[1]=0.569896;
a3[2]=0.502116;
a3[3]=0.432653;
a3[4]=0.343625;
a3[5]=0.512472;
a3[6]=0.56708;
a3[7]=1.01459;
a3[8]=2.32799;
a3[9]=3.67962;
a3[10]=4.48398;
std::cout.precision(10);
std::copy(a3,a3+n,a1);
for(int i=0;i<n;i++) a1[i]+=x[i];
std::sort(a1,a1+n);
for(int i=0;i<n;i++) std::cout << a1[i] << std::endl;
std::cout << "---" << std::endl;
int n_1=std::unique(a1,a1+n)-a1;
std::cout << "length of unique subvector " << n_1 << std::endl;
std::cout << "---" << std::endl;
for(int i=0;i<n_1;i++) std::cout << a1[i] << std::endl;
std::cout << "---" << std::endl;
}
but when I'm running this code (link to coliru)
it returns:
original array
0.073053
0.073053
0.073053
0.073054
0.138018
0.5855256
0.705098
1.600116
4.72903
7.4323
9.04102
---
length of unique subarray 10
---
unique array
0.073053
0.073053
0.073054
0.138018
0.5855256
0.705098
1.600116
4.72903
7.4323
9.04102
---
the unique array still contains a duplicate (and so is wrong)!
what am I doing wrong?
Let's try with a bit more precision, std::cout.precision(20):
0.073052999999999979064
0.073053000000000034575
0.073053999999999952308
0.13801800000000000179
0.58552559999999997942
0.70509800000000000253
1.6001160000000000938
4.7290299999999998448
7.4322999999999996845
9.0410199999999996123
Since most decimal fractions can't be represented exactly by a binary floating point format, slightly different rounding errors cause slightly different results.
In general, you can't expect the results of different floating point calculations to be exactly equal, even if the corresponding calculations applied to mathematical real numbers would be.
You could instead test for "almost equality", carefully choosing a tolerance that's appropriate for your numerical domain. unique allows you to specify your own predicate, instead of a simple equality test:
std::unique(a1,a1+n,[](double x, double y){return std::abs(x-y) < tolerance;});
How about:
int n_1 = std::unique(a1,a1+n,
[](float a, float b)
{
return std::fabs(a-b) < 10e-9;
}
) - a1;
?
Live demo link

C++ precision - behaviour of setprecision

As I understand it the setprecision function specifies the minimal precision but when I run the following code I get only 3 numbers after the decimal point:
int main()
{
double a = 123.4567890;
double b = 123.4000000;
std::cout << std::setprecision(5) << a << std::endl; // Udesireble
std::cout.setf(std::ios::fixed);
std::cout << std::setprecision(5) << a << std::endl; // Desireble
std::cout << std::setprecision(5) << b << std::endl; // Udesireble
std::cout.unsetf(std::ios::fixed);
std::cout << std::setprecision(5) << b << std::endl; // Desireble
return 0;
}
which prints:
123.46 // Udesireble
123.45679 // Desireble
123.40000 // Udesireble
123.4 // Desireble
Is there any way I can avoid checking the number of digits after the decimal point myself in order to know whether to set fixed ?
My impression is that you will need to format to string first, and then replace trailing zeros with spaces.
For the streams, you can use two functions.
setfill(char_type c), which set the character to write, to match with the number of needed character (more information here)
There is the setw(int) function, which set the width of field of the value to display. (documentation here )
Using these functions, you may have a solution

std::cout << Predicting the automatic field width in displayed for an arbitrary double

I'm displaying a large number of doubles on the console, and I would like to know in advance how many decimal places std::cout will decide to display for a given double. This is basically so I can make it look pretty in the console.
e.g. (pseudo-code)
feild_width = find_maximum_display_precision_that_cout_will_use( whole_set_of_doubles );
...
// Every cout statement:
std::cout << std::setw( feild_width ) << double_from_the_set << std::endl;
I figure cout "guesses"? a good precision to display based on the double. For example, it seems to display
std::cout << sqrt(2) << std::endl;
as 1.41421, but also
std::cout << (sqrt(0.5)*sqrt(0.5) + sqrt(1.5)*sqrt(1.5)) << std::endl;
as 2 (rather than 2.000000000000?????? or 1.99999999?????). Well, maybe this calculates to exactly 2.0, but I don't think that sqrt(2) will calculate to exactly 1.41421, so std::cout has to make some decision about how many decimal places to display at some point, right?
Anyway possible to predict this to formulate a find_maximum_display_precision...() function?
What you need is the fixed iomanip.
http://www.cplusplus.com/reference/iostream/manipulators/fixed/
double d = 10/3;
std::cout << std::setprecision(5) << std::fixed << d << std::endl;
Sometimes C++ I/O bites. Making pretty output is one of those sometimes. The C printf family is easier to control, more understandable, more terse, and isn't plagued with those truly awful ios:: global variables. If you need to use C++ output for other reasons, you can always sprintf/snprintf to a string buffer and then print that using the << to stream operator. IMHO, If you don't need to use C++ output, don't. It is ugly and verbose.
In your question you are mixing precision and width, which are two different things.
Other answers concentrate on precision, but the given precision is the maximum, not a minimum of displayed digits. It does not pad trailing zeros, if not ios::fixed or ios::scientific is set.
Here is a solution to determine the number of characters used for output, including sign and powers of 10:
#include <string>
#include <sstream>
#include <vector>
size_t max_width(const std::vector<double>& v)
{
size_t max = 0;
for (size_t i = 0; i < v.size(); ++i)
{
std::ostringstream out;
// optional: set precision, width, etc. to the same as in std::cout
out << v[i];
size_t length = out.str().size();
if (length > max) max = length;
}
return max;
}
std::cout::precision(); use it to determine precision
example :
# include <iostream>
# include <iomanip>
int main (void)
{
double x = 3.1415927
std::cout << "Pi is " << std::setprecision(4) << x << std::endl;
return 1;
}
This would display:
Pi is 3.142
This link also includes explanation for std::cout::precision();
http://www.cplusplus.com/reference/iostream/ios_base/precision/

Platform-independent way to obtain maximum C++ float value

What’s the best, platform-independent way to obtain the maximum value that can be stored in a float in C++?
std::numeric_limits
std::numeric_limits<float>::max()
std::numeric_limits
// numeric_limits example
#include <iostream>
#include <limits>
using namespace std;
int main () {
cout << "Minimum value for float: " << numeric_limits<float>::min() << endl;
cout << "Maximum value for float: " << numeric_limits<float>::max() << endl;
cout << "Minimum value for double: " << numeric_limits<double>::min() << endl;
cout << "Maximum value for double: " << numeric_limits<double>::max() << endl;
return 0;
}
In C++ you can use the std::numeric_limits class to get this sort of information.
If has_infinity is true (which will be true for basically all platforms nowadays), then you can use infinitity to get the value which is greater than or equal to all other values (except NaNs). Similarly, its negation will give a negative infinity, and be less than or equal to all other values (except NaNs again).
If you want finite values, then you can use min/max (which will be less than or equal to/greater than or equal to all other finite values).
#include <float.h>
then use FLT_MAX