Declaration - Calculation?

Jun 21, 2013 at 5:58am
When I try to execute this program, I get 1 as o/p which is obviously correct.
1
2
3
4
5
6
7
8
9
10
11
#include<iostream.h>
void main()
{
	long double x=400;
	x*=400;
	x/=400;
	if(x==400)
		cout<<"1";
	else
		cout<<"2";
}

But when i try to calculate the whole thing for var "x" in its declaration, it prints 2.
long double x=400*400/400;
gives
2

Actually it prints "2" for any calculation whose result will contain more than 6 digits (i guess). Can anyone tell me why? I really don't seem to get it given I've been using long double..it's range is supposed to be more than just 6 digits, right?
Jun 21, 2013 at 7:45am
Have you tried just printing out the result of the calculation to see what is it? That would have been a quicker way to find out what was going on than writing a question here and waiting to see if someone answers.
Last edited on Jun 21, 2013 at 7:46am
Jun 21, 2013 at 10:33am
The type of 400*400/400 and all its sub-expressions are int. It is not until it is assigned to x that it gets value long double.
Jun 21, 2013 at 10:49am
Just to illustrate Peter87's point in code form...

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <typeinfo>

int main( int argc, char* argv[] )
{
  std::cout << "Type of calc is " << typeid( 400*400/400 ).name() << std::endl;
  long double ld = 400 * 400 / 400;
  std::cout << "Type of ld is " << typeid( ld ).name() << std::endl;

  return 0;
}


Output
Type of calc is int
Type of ld is long double
Jun 21, 2013 at 11:34am
still why doesn't the value of that int expression evaluate to 400? Does its value change on being assigned to a long double variable?
Jun 21, 2013 at 11:43am
Not sure about that. This evaluates fine for me...

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main( int argc, char* argv[] )
{
  long double x = 400 * 400 / 400;

  std::cout << "x " << ( x == 400 ? "is " : "is not " ) << "400\n";

  return 0;
}
Jun 21, 2013 at 11:57am
works as expected for me as well (VS 2010 premium).
Jun 21, 2013 at 12:33pm
> Peter87: The type of 400*400/400 and all its sub-expressions are int.

+1


> abhishekm71: still why doesn't the value of that int expression evaluate to 400?

There is a big clue here:
"Actually it prints "2" for any calculation whose result will contain more than 6 digits (i guess)"

There is an integer overflow; the program is being run on an implementation with 16-bit int
ie. std::numeric_limits<unsigned int>::digits == 16

Try this:
1
2
3
4
5
6
7
8
#include <iostream>
#include <cstdint>

int main ()
{
    long double x = std::int16_t(400*400) / 400 ;
    std::cout << x << '\n' ;
}
Jun 21, 2013 at 1:12pm
Or, more appropriately put the decimals in like C++ really wants you to.

long double x=400.0*400.0/400.0;
Jun 21, 2013 at 2:06pm
oh wow! couldn't guess it was a case of integer overflow.

thanks Peter87 and JLBorges
Jun 30, 2013 at 2:42pm
Ah, thanks a lot, everyone.
That really helped.
Topic archived. No new replies allowed.