I want to print only one digit after the decimal dot.
So I write:
double number1 = -0.049453;
double number2 = -0.05000;
cout.setf(ios::fixed,ios::floatfield);
cout.precision(1);
cout << number1 << endl;
cout << number2 << endl;
My output is:
-0.0
-0.1
I want that the first line will be 0.0 (cause -0.0 is 0.0). How should I change my code that in a case of -0.0, it will print 0.0?
And about the second line, why doesn't it print 0.0 (or -0.0)?
Any help appreciated!
To print floating point numbers, they are rounded up if they are greater or equal to the "middle" of two possible outputs, so -0.05 becomes -0.0 intentionally.
Negative zero is the result if a negative number is rounded up to zero, also intentionally. The internal floating point format (IEEE 754) distinguishes between negative and positive zero (see this link), and it seems like C++ output streams stick to this behavior.
You can overcome both problems by separating printing the sign and the absolute value of the floating point number.
cout << (number <= -.05 ? "-" : "") << abs(number);
Explanation of the comparison: For numbers equal to or smaller than -0.05, rounding abs(number) (which is then >= 0.05) will be non-zero, so only then you want the sign to appear.
Note that the threshold value in this comparison depends on the output format you chose. So you should keep this printing method as local as possible in your code, where you know the exact format you want to print floating pointers.
Live example
Note: float and double behave exactly the same regarding these points.
Related
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 to be able to sort negative zeros and zeros for an assignment i am doing at university using c++, could someone tell me why the following code does produce a negative zero? i'm stuck and i am not sure why this works...
cout << "Enter the number of elements you want to add to the vector:\n";
cin >> x;
cout << "Enter the integers: \n" << endl;
for (int i = 0; i < x; i++)
{
cin >> y;
y = y - 0.0;
cout << y;
Array.push_back(y);
}
If there is a better way of producing a negative zero when sorting the above vector please advise.
Many thanks!
First of all, there need not be any negative zeroes in standard C++, so I assume you are talking about the negative zero from IEEE-754, which is what most (I never encountered an exception) C++ implementations base their floating point math on.
In this case, the expression
y = y - 0.0;
will yield -0.0 only if either y == -0.0 before that assignment or if you set your rounding mode to "round towards -INFINITY", which you usually won't.
To actually produce a double with the value -0.0, you can just assign the desired value:
double d = -0.0;
Now d == -0.0 in IEEE floating point math.
However, as
Comparisons shall ignore the sign of zero
(IEEE 754-1985, 5.7. Comparison), -0.0 < 0.0 will yield false, so if you actually want to sort negative zero before positive zero, you will need to write your own comparator, possibly using std::signbit.
Appendix: Relevant standard quote:
When the sum of two operands with opposite signs (or the difference of two
operands with like signs) is exactly zero, the sign of that sum (or difference)
shall be + in all rounding modes except round toward –INFINITY, in which
mode that sign shall be –.
IEEE 754-1985, 6.3 (The Sign Bit)
In the below example the output is 3.1 so it starts at the first value.
double y = 3.14784;
cout << setprecision(2) << y;
in the following example the output precision starts at the decimal value
int x = 2;
double y = 3.0;
cout << setprecision(2) << x/y;
and yet in the following line of code - same x and y as declared above we get the precision starting not at all shown. (the only way for the below to print 6.00 is if we use fixed).
cout << setprecision(2) << x * y; // shows 6.
if we aren't using fixed - just a setprecision(n) where does that n start? because it states that its a set precision is used for decimal precision. and yet in the first example it looks at the whole double value and not just the decimal.
please advise.
thanks.
From http://www.cplusplus.com/reference/ios/ios_base/precision/
For the default locale:
Using the default floating-point notation, the precision field specifies the maximum number of meaningful digits to display in total counting both those before and those after the decimal point. Notice that it is not a minimum, and therefore it does not pad the displayed number with trailing zeros if the number can be displayed with less digits than the precision.
In both the fixed and scientific notations, the precision field specifies exactly how many digits to display after the decimal point, even if this includes trailing decimal zeros. The digits before the decimal point are not relevant for the precision in this case.
n starts from the first meaningful digits(non-zero)
Is there any standard way to set an ostream to print signed 0.0 uniformly without sign?
Or is this the simplest possible solution?:
double d = -0.0;
std::cout << ( d==0 ? 0.0 : d);
Edit:
I don't want to abs all, because I want to see non-0 negative numbers. I just don't want to see -0.0 (and I mean real -0, not very near ones). Can happen if you have e.g. a data set double data[100]; and mirror it: for(...) data[i]*=-1;. And a -0.0 output because of floatfield fixed and small precision would also be OK for near 0 negative numers.
You can also try to print it like this
std::cout << ( 0.0 + d);
double d = 0;
std::cout.precision(1);
std::cout.setf(std::ios::fixed);
std::cout << d << std::endl;
This prints 0.0. The precision() call sets the (maximum) number of decimal places to display, and the std::ios::fixed manipulator tell is to use all of those decimal places even if they are zero.
EDIT: If you're seeing a minus sign, as others have pointed out, it could be due to a rounding error. Note that there is also such a thing as "negative zero" in IEEE floating point numbers. If this is the real problem then you'll have to write code to check if your number is "close to" zero and if so, print it as exactly zero.
I have simple question about floating number,
double temp;
std::cout.precision(std::numeric_limits<double>::digits10);
temp = 12345678901234567890.1234567890;
std::cout << (temp < std::numeric_limits<double>::max()) << std::endl;
std::cout << std::fixed << std::endl;
std::cout << temp << std::endl;
However, the output I get is this,
1
12345678901234567168.000000000000000
The value of temp is still within the range of double, however, the value is completely different. I am wondering what have I done wrong here?
Thanks.
A double has only 15.95 decimal digits of precision. You've already exceeded this number of digits in the integer part of the value, hence the loss of precision in the last few digits, and the lack of any useful digits after the decimal point.
You should probably take a look at this: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html before doing any more work with floating point values.
It's not completely different. It's correct to 16 digits or so. That's about what you can expect from a double.
A double can only store a limited amount of precision. It works out to about 15 decimal digits.
Here's a helpful article on how floating point numbers are represented, and the implications of that representation: Float
IEEE 754 is not precise for any given value - for example http://www.cprogramming.com/tutorial/floating_point/understanding_floating_point.html and http://support.microsoft.com/kb/42980
-358974.27 can't be represented on float according to http://ridiculousfish.com/blog/posts/float.html and I remember (though I'm too lazy to test it) that even something "simple" like 2.2 or 2.3 can't be accurately represented even as a double.