1

I have two input and the only difference is that I replace the "double" with "float" in the second input. However, the first one can run as expected but not the second one.The second one does not end with the input of 0.1. Any one have some ideas on this? Thanks very much!

First input:

#include <iostream>

using namespace std;

int main()
{
    double input;
    input = 0;
    double sum = 0;
    cout << "Please enter a series numbers and end with 0.1: ";
    cin >> input;
    while (input != 0.1)
    {
        sum += input;
        cout << "The cumulative sum is: " << sum << endl;
        cin >> input;
    }
    return 0;
}


Please enter a series numbers and end with 0.1: 1 2 3 0.1
The cumulative sum is: 1
The cumulative sum is: 3
The cumulative sum is: 6

Second input:

#include <iostream>
using namespace std;

int main()
{
    float input;
    input = 0;
    float sum = 0;
    cout << "Please enter a series numbers and end with 0.1: ";
    cin >> input;
    while (input != 0.1)
    {
        sum += input;
        cout << "The cumulative sum is: " << sum << endl;
        cin >> input;
    }
    return 0;
}


Please enter a series numbers and end with 0.1: 1 2 3 0.1
The cumulative sum is: 1
The cumulative sum is: 3
The cumulative sum is: 6
The cumulative sum is: 6.1
Niall
  • 30,036
  • 10
  • 99
  • 142
Xiang Wang
  • 69
  • 1
  • An alternative is to say "end with 'end'" or any other text, and make your loop condition be `while (cin)` (or even better, `while (cin >> input)` and get rid of the other two duplicate instances of `cin >> input`). If they input something that's not a valid float then the loop will end. – M.M Oct 06 '14 at 06:35

2 Answers2

6

0.1 in the condition (input != 0.1) is the double closest to the rational 1/10. The float closest to this rational, 0.1f, represents a different value and does not make this condition true.

If you want to use float in your program, use (input != 0.1f) as the corresponding condition.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • 6
    And in general you should never compare floating-point numbers for equality anyway. See http://stackoverflow.com/questions/588004/is-floating-point-math-broken – o11c Oct 06 '14 at 05:40
  • 1
    @o11c I compare floating-point numbers for equality all the time. – Pascal Cuoq Oct 06 '14 at 06:19
  • 1
    Nothing wrong with comparing floating-point numbers - you just need to deeply understand what you're doing. Which most "newby" programmers will not. – Michael Anderson Oct 06 '14 at 06:49
  • @PascalCuoq given that `a + b` is not guaranteed to be equal to `a + b`, because of how excess precision works, I'm glad I'm not you. – o11c Oct 06 '14 at 07:17
  • 2
    @o11c To be fair, I do most of my programming in C, for which the last two standards are more emphatic than the C++ ones about the conditions that allow excess precision or not. I sometimes argue that C++11, which describe `cfloat` with the sentence “The contents are the same as the Standard C library header ”, should have the same rules since this header defines `FLT_EVAL_METHOD`, but this is a tenuous argument not believed by GCC's authors, for instance (since they did not let option `-fexcess-precision=standard` apply to the C++ front-end). – Pascal Cuoq Oct 06 '14 at 08:28
  • 1
    @o11c In general, you should know what you are doing when dealing with floating point numbers. There are times you should compare for equality, and times you shouldn't. (His loop would work with `float` if he compared with `1.0f`, for example. Not that it's a good example for when you should compare for equality.) – James Kanze Oct 06 '14 at 09:02
  • 1
    @o11c I think you just proved @PascalCuoq's point. `a + b` will be equal to `b + a`, always. The reference for floating point is http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html; if you don't fully understand this paper, then you probably shouldn't be using floating point at all. – James Kanze Oct 06 '14 at 09:04
  • 1
    @PascalCuoq As far as I know, the _intent_ of C++ is to be identical with C for everything concerning the basic arithmetic types. (But there are regrettable cases where the rewording in the C++ standard doesn't fulfill this intent.) – James Kanze Oct 06 '14 at 09:07
  • @PascalCuoq And I would consider not supporting the standard interpretation for excess precision a compiler error. – James Kanze Oct 06 '14 at 09:09
  • @JamesKanze the [famous gcc bug report](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323) gives an example of when it is *not*. – o11c Oct 06 '14 at 09:37
  • 1
    @o11c `a+b` differing from `a+b` when the rules for `FLT_EVAL_METHOD` predict they should be equal was a GCC bug. This bug has been fixed (for the C front-end—use `-std=c99` or `-fexcess-precision=standard`): https://gcc.gnu.org/ml/gcc-patches/2008-11/msg00105.html . If any construct that has been miscompiled in the past must now be avoided, we will never get any code written. – Pascal Cuoq Oct 06 '14 at 09:46
  • 1
    @o11c `a + b` will always return the same value. It's what you do with it afterwards which makes the difference; in particular, the value may not be representable in a `double` (even if `a` and `b` are `double`). As I said before, you have to understand how machine floating point works; there is no silver bullet. (Having said that: the first example in the thread you quote is clearly a bug, since he is comparing two `double` variables, not the results of an expression.) – James Kanze Oct 06 '14 at 09:52
1

You have to explicitly cast 0.1 to float like:

while(input != (float)0.1)  

It is better to use explicit conversions while comparing floating point numbers.

Ashwani
  • 1,938
  • 11
  • 15
  • Comparing two floating point numbers is dangerous, if not today, in 7 years it'll be. – The Mean Square Oct 06 '14 at 06:15
  • Not only that, there is no need to cast a constant. Just append an 'f'. – Yamakuzure Oct 06 '14 at 06:45
  • 2
    Although it works for 0.1, in general there is no guarantee that converting a double literal to float will give the float closest to the nominal value of the literal. There are exceptions where the two step rounding, from decimal to double and from double to float, introduces additional rounding error. – Patricia Shanahan Oct 06 '14 at 12:46