views:

311

answers:

8

Possible Duplicates:
Incorrect floating point math?
Float compile-time calculation not happening?

Strange stuff going on today, I'm about to lose it...

#include <iomanip>
#include <iostream>
using namespace std;

int main()
{
    cout << setprecision(14);
    cout << (1/9+1/9+4/9) << endl;
}

This code outputs 0 on MSVC 9.0 x64 and x86 and on GCC 4.4 x64 and x86 (default options and strict math...). And as far as I remember, 1/9+1/9+4/9 = 6/9 = 2/3 != 0

+31  A: 

1/9 is zero, because 1 and 9 are integers and divided by integer division. The same applies to 4/9.

If you want to express floating-point division through arithmetic literals, you have to either use floating-point literals 1.0/9 + 1.0/9 + 4.0/9 (or 1/9. + 1/9. + 4/9. or 1.f/9 + 1.f/9 + 4.f/9) or explicitly cast one operand to the desired floating-point type (double) 1/9 + (double) 1/9 + (double) 4/9.

P.S. Finally my chance to answer this question :)

AndreyT
+1, as are all of the other terms in the addition expression.
Adam Robinson
If you're naming double and float, you might as well name long double: 1L
René Wolferink
1L is a long, not a long double, and 1L/3 is still 0.
6502
1l is a long (1l/3 == 0), 1L is a long double (1L / 3 != 0). See http://www.cplusplus.com/doc/tutorial/constants/ for all kinds of constants.
René Wolferink
@René Wolferink: The capitalization of the `L` is inconsequential. Both `l` and `L` when attached to an integer literal make it long, and when attached to a floating literal make it a long double (actually, that page you link even says as much). @AndreyT: Isn't it necessary to have `1.0f` instead of `1f`? I don't think a floating suffix is valid if there is no decimal point or exponent.
James McNellis
@James McNellis: You are absolutely right. It does have to be a floating-point literal, meaning that it needs a decimal point at least. I.e. `1.f` is OK, while my original `1f` is invalid.
AndreyT
+4  A: 
1/9(=0)+1/9(=0)+4/9(=0) = 0
aJ
+5  A: 

They are all integers. So 1/9 is 0. 4/9 is also 0. And 0 + 0 + 0 = 0. So the result is 0. If you want fractions, cast your fractions to floats.

René Wolferink
+3  A: 

well, in C++ (and many other languages), 1/9+1/9+4/9 is zero, because it is integer arithmetic.

You probably want to write 1/9.0+1/9.0+4/9.0

frunsi
+6  A: 

Use a decimal point in your calculations to force floating point math optionally along with one of these suffixes: f l F L on your numbers. A number alone without a decimal point and without one of those suffixes is not considered a floating point literal.

C++03 2.13.3-1 on Floating literals:

A floating literal consists of an integer part, a decimal point, a fraction part, an e or E, an optionally signed integer exponent, and an optional type suffix. The integer and fraction parts both consist of a sequence of decimal (base ten) digits. Either the integer part or the fraction part (not both) can be omitted; either the decimal point or the letter e (or E) and the exponent (not both) can be omitted. The integer part, the optional decimal point and the optional fraction part form the significant part of the floating literal. The exponent, if present, indicates the power of 10 by which the significant part is to be scaled. If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner. The type of a floating literal is double unless explicitly specified by a suffix. The suffixes f and F specify float, the suffixes l and L specify long double. If the scaled value is not in the range of representable values for its type, the program is ill-formed. 18

Brian R. Bondy
Or use perhaps boost::rational if you're just going to be throwing a lot of fractions around.
Owen S.
+2  A: 

Unless you specifically specify the decimal, the numbers C++ uses are integers, so 1/9 = 4/9 = 0 and 0 + 0 + 0 = 0.

You should simply add the decimal 1.0 etc...

Jordan
+2  A: 

By the C rules of types, you're doing all integer math there. 1/9 and 4/9 are both truncated to 0 (as integers). If you wrote 1.0/9.0 etc, it would use double precision math and do what you want.

Mark B
A: 

You might make it a habit to use more parentheses. They cost little time, make clear what you intend, and ensure you get what you wanted. Well mostly... ;)

Jay
Parentheses in the posted expression serve only to clutter it and make something completely readable less readable. They have nothing to do with the problem in hand and inserting parentheses doesn't answer the poster's question.
I completely disagree. Adding parenthesis to force order of evaluation eliminates ambiguity and can prevent subtle errors. I find it hard to believe a couple of parenthesis will make the code unreadable. I also can't agree with placing readability of the source code as more important than code that works.
Jay