VS 2003 bug, Can not even correctly compile a simple c++ program?

L

LTO

What is going on with MS VC compiler team? The following trivial program
will give wrong answer of 9 instead of 10. Perhaps MS is spending too much
time on managed world and forget about the real world. If we can not
multiply two numbers and get a right answer, what good is it ?

// test_int.cpp : Defines the entry point for the console application.
// the program will give wrong answer for ftemp=0.01,0.02,0.03,0.04

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
int itemp;
float ftemp = 0.01f;
cout << ftemp*1000.f << endl;
cout << int(ftemp*1000.f) << endl;
cin >> itemp;
return 0;
}
 
C

Carl Daniel [VC++ MVP]

LTO said:
What is going on with MS VC compiler team? The following trivial
program will give wrong answer of 9 instead of 10. Perhaps MS is
spending too much time on managed world and forget about the real
world. If we can not multiply two numbers and get a right answer,
what good is it ?

Or perhaps you're spending too little time understanding what the code you
write means.

The number 0.01 cannot be represented accurately in floating point (no
negative power of 10 can be). So instead of 0.01, it's really 0.0099999...,
so when you multiply it by 1000 (which is represented accurately), the
result is 9.99999..., which is 9 when it's truncated to an integer. If you
want rounding, you have to ask for it.
// test_int.cpp : Defines the entry point for the console application.
// the program will give wrong answer for ftemp=0.01,0.02,0.03,0.04

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
int itemp;
float ftemp = 0.01f;
cout << ftemp*1000.f << endl;
cout << int(ftemp*1000.f) << endl;

cout << int(ftemp * 1000.0f + 0.5) << endl;
cin >> itemp;
return 0;
}

-cd
 
L

LTO

Sorry! I didn't mean to be rude. I just got a litle bit upset because a
whole afternoon was wasted because of this. Anyway, the code can be modified
to make it work for all case:
cout << int((ftemp*1000.f)+0.1f) << endll;
Thanks for pointing out my short sightedness!

Carl Daniel said:
LTO said:
What is going on with MS VC compiler team? The following trivial
program will give wrong answer of 9 instead of 10. Perhaps MS is
spending too much time on managed world and forget about the real
world. If we can not multiply two numbers and get a right answer,
what good is it ?

Or perhaps you're spending too little time understanding what the code you
write means.

The number 0.01 cannot be represented accurately in floating point (no
negative power of 10 can be). So instead of 0.01, it's really 0.0099999...,
so when you multiply it by 1000 (which is represented accurately), the
result is 9.99999..., which is 9 when it's truncated to an integer. If you
want rounding, you have to ask for it.
// test_int.cpp : Defines the entry point for the console application.
// the program will give wrong answer for ftemp=0.01,0.02,0.03,0.04

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
int itemp;
float ftemp = 0.01f;
cout << ftemp*1000.f << endl;
cout << int(ftemp*1000.f) << endl;

cout << int(ftemp * 1000.0f + 0.5) << endl;
cin >> itemp;
return 0;
}

-cd
 
C

Carl Daniel [VC++ MVP]

Floating point results are never precise, except by coincidence. Some
numbers that can't be represented exactly will actually be slightly larger
than the "true" value, while others will be slightly smaller. Depending on
the exact calculation you're performing, the slightly larger ones may lead
to the "correct" result, while for a different calculation, the slightly
smallers ones might give the "correct" answer.

The thing to realize is that all floating point is inexact. You absolutely
must think about and control rounding and precision issues in every floating
point expression you write.

-cd
Ok, the number 0.01 can not be represented precisely in floating
point. Then why does the compiler generate program which produces
precise answers to ftemp = 0.1 and 0.001? Thanks!

Carl Daniel said:
LTO said:
What is going on with MS VC compiler team? The following trivial
program will give wrong answer of 9 instead of 10. Perhaps MS is
spending too much time on managed world and forget about the real
world. If we can not multiply two numbers and get a right answer,
what good is it ?

Or perhaps you're spending too little time understanding what the
code you write means.

The number 0.01 cannot be represented accurately in floating point
(no negative power of 10 can be). So instead of 0.01, it's really
0.0099999..., so when you multiply it by 1000 (which is represented
accurately), the result is 9.99999..., which is 9 when it's
truncated to an integer. If you want rounding, you have to ask for
it.
// test_int.cpp : Defines the entry point for the console
application. // the program will give wrong answer for
ftemp=0.01,0.02,0.03,0.04

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
int itemp;
float ftemp = 0.01f;
cout << ftemp*1000.f << endl;
cout << int(ftemp*1000.f) << endl;

cout << int(ftemp * 1000.0f + 0.5) << endl;
cin >> itemp;
return 0;
}

-cd
 
B

Bo Persson

LTO said:
Sorry! I didn't mean to be rude. I just got a litle bit upset because a
whole afternoon was wasted because of this. Anyway, the code can be modified
to make it work for all case:
cout << int((ftemp*1000.f)+0.1f) << endll;

No, this doesn't work for all cases, just for your test case. The
general solution is to add 0.5 (or a value half the last digit you are
rounding to), like Carl showed you. Consider these cases:

trunc(1.4 + 0.5) == trunc(1.9) == 1
trunc(1.6 + 0.5) == trunc(2.1) == 2

Less than x.5 is rounded to x
Greater or equal to x.5 is rounded to x+1


Bo Persson
(e-mail address removed)
 
G

Gabest

No, this doesn't work for all cases, just for your test case. The
general solution is to add 0.5 (or a value half the last digit you are
rounding to), like Carl showed you. Consider these cases:

trunc(1.4 + 0.5) == trunc(1.9) == 1
trunc(1.6 + 0.5) == trunc(2.1) == 2

Less than x.5 is rounded to x
Greater or equal to x.5 is rounded to x+1

Now, the big question is, what will be the result of trunc(x.5 + 0.5)? :)
 
M

Mike Kosak

OK, then why does the following give the answers 9 and 10
for what appears to be the same value?
int itemp;
float ftemp = 0.01f;
CString temp;
temp.Format ("%f", ftemp*1000.f);
SetDlgItemText(IDC_RESULT, temp);
float t = ftemp*1000.f;
SetDlgItemInt ( IDC_RESULT2, int(t));
SetDlgItemInt ( IDC_RESULT3, int(ftemp*1000.f));
the results in the edit boxes are
10.00000000
10
9

-----Original Message-----
Floating point results are never precise, except by coincidence. Some
numbers that can't be represented exactly will actually be slightly larger
than the "true" value, while others will be slightly smaller. Depending on
the exact calculation you're performing, the slightly larger ones may lead
to the "correct" result, while for a different calculation, the slightly
smallers ones might give the "correct" answer.

The thing to realize is that all floating point is inexact. You absolutely
must think about and control rounding and precision issues in every floating
point expression you write.

-cd
Ok, the number 0.01 can not be represented precisely in floating
point. Then why does the compiler generate program which produces
precise answers to ftemp = 0.1 and 0.001? Thanks!

LTO wrote:
What is going on with MS VC compiler team? The following trivial
program will give wrong answer of 9 instead of 10. Perhaps MS is
spending too much time on managed world and forget about the real
world. If we can not multiply two numbers and get a right answer,
what good is it ?

Or perhaps you're spending too little time understanding what the
code you write means.

The number 0.01 cannot be represented accurately in floating point
(no negative power of 10 can be). So instead of 0.01, it's really
0.0099999..., so when you multiply it by 1000 (which is represented
accurately), the result is 9.99999..., which is 9 when it's
truncated to an integer. If you want rounding, you have to ask for
it.


// test_int.cpp : Defines the entry point for the console
application. // the program will give wrong answer for
ftemp=0.01,0.02,0.03,0.04

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
int itemp;
float ftemp = 0.01f;
cout << ftemp*1000.f << endl;
cout << int(ftemp*1000.f) << endl;

cout << int(ftemp * 1000.0f + 0.5) << endl;

cin >> itemp;
return 0;
}

-cd


.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top