By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,412 Members | 917 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,412 IT Pros & Developers. It's quick & easy.

static_cast<unsigned int> question...

P: n/a
Hello,

I'm (very) new to c++ and I'm having trouble understanding why this doesn't
work. Here's some testcode:

#include <iostream.h>

int main()
{
float test;
unsigned int test2;
test = 1.8;
cout << "\n" << test*100.0 << endl;
test2 = static_cast<unsigned int>(test*100.0);
cout << "\n" << test2 << endl;

}
The strange thing is that the program returns 180 on the first cout (as
expected) but it returns 179 on the second ???
If I make test 1.7, I get 170 on the first and second cout ???
I tried a whole bunch of other values... Sometimes I'm getting what I
expected, sometimes not...

Can anyone explain this to me ?

Tnx in advance,

Tom
Jul 19 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Its nothing to do with static_cast and it is not needed.

test2 = static_cast<unsigned int>(test*100.0);
Probably your processor only does 64 bit floating point. float is 32bit.
The float of 1.8 is converted to a double of something like 1.7999999513.

The standard says:
The values of the floating operands and the results of floating
expressions may be represented in greater precision and range than
that required by the type; the types are not changed thereby

The truncation to unsinged int made the loss of precision.

Fraser.
Jul 19 '05 #2

P: n/a


GuineaPig wrote:

Hello,

I'm (very) new to c++ and I'm having trouble understanding why this doesn't
work. Here's some testcode:

#include <iostream.h>

int main()
{
float test;
unsigned int test2;
test = 1.8;
cout << "\n" << test*100.0 << endl;
test2 = static_cast<unsigned int>(test*100.0);
cout << "\n" << test2 << endl;

}

The strange thing is that the program returns 180 on the first cout (as
expected) but it returns 179 on the second ???
That's because you computer cannot store the value 1.8 exactly.
It may be stored as 1.7999999999999999... or 1.80000000000001 or
something like that.

Multiplying with 100 gives 179.9999999999999999... or
180.0000000000001 or something like that.

When operator<< outputs a floating point number, this number is
rounded to x decimal digits (usually x equals 6, if nothing else specified).
So rounding 179.99999999999999 to 6 digits yields (surprise) 180.000000
Rounding 180.00000000000001 to six digits also yields 180.000000
(and of course the superflous decimal digits are not output).

Note: The number was *rounded* in order to be printed.

The cast does a very different thing. The cast truncates the
decimal digits from a number.

179.9999999999999999 is close to 180.0, but that doesn't
matter. Truncating the decimal digits still leaves you with
179.

180.0000000000000001 is also close to 180.0, but this time
truncating the decimal digits leaves you with 180.

The difference: rounding gives a different result then truncating.
If I make test 1.7, I get 170 on the first and second cout ???
I tried a whole bunch of other values... Sometimes I'm getting what I
expected, sometimes not...


It depends on how the numbers are stored. Note: A computer cannot
store every floating point number exactly. In the range 0 .. 1
there are indefinitly many floating point numbers and your computer
only has a finite memory.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #3

P: n/a
> I'm (very) new to c++ and I'm having trouble understanding why this
doesn't
work. Here's some testcode:

#include <iostream.h>

int main()
{
float test;
unsigned int test2;
test = 1.8;
cout << "\n" << test*100.0 << endl;
test2 = static_cast<unsigned int>(test*100.0);
cout << "\n" << test2 << endl;

}

The strange thing is that the program returns 180 on the first cout (as expected) but it returns 179 on the second ???
If I make test 1.7, I get 170 on the first and second cout ???
I tried a whole bunch of other values... Sometimes I'm getting what I
expected, sometimes not...

Can anyone explain this to me ?


This is caused by the way the float type store number internally. Some
numbers cannot be exactly represented in floating point format; only a
approximation of the number is stored. Because of this 1.8*100.0 may
produce 179.9999952. The reason you see 180.000 is because the result is
rounded before it is printed. When you change the line that outputs the
floating point value to:

cout << "\n" << std::setprecision(10) << test*100.0 << endl;

You will probably see that test*100.0 is not exactly 180.0

When casting to in the part behind the decimal point will be truncated
so the result will be 179.

This is also the reason why comparing two floating point values with the
== operator is usually wrong. For example the program below will (most
likely) output the text "Not equal", because the number 1.23 cannot be
exactly represented in IEEE-754 floating point format (which most
implementations use for floating point numbers):

#include <iostream>
int main()
{
float f = 1.23;

if(f*2 == 2.46)
{
std::cout << "Equal\n";
}
else
{
std::cout << "Not Equal\n";
}

return 0;
}
--
Peter van Merkerk
peter.van.merkerk(at)dse.nl

Jul 19 '05 #4

P: n/a
GuineaPig <gu*******@pi.be> wrote in message news:<bp**********@reader11.wxs.nl>...
Hello,

I'm (very) new to c++ and I'm having trouble understanding why this doesn't
work. Here's some testcode:

#include <iostream.h>

int main()
{
float test;
unsigned int test2;
test = 1.8;
cout << "\n" << test*100.0 << endl;
test2 = static_cast<unsigned int>(test*100.0);
cout << "\n" << test2 << endl;

}
The strange thing is that the program returns 180 on the first cout (as
expected) but it returns 179 on the second ???
If I make test 1.7, I get 170 on the first and second cout ???
I tried a whole bunch of other values... Sometimes I'm getting what I
expected, sometimes not...

Can anyone explain this to me ?

Tnx in advance,

Tom


Because float is not an accurate data type.
For example, an integer 1 add up for 1000 times, you get 1000, but if
you add float 0.1 for 1000 times, you may get 99.999, not 100.
Jul 19 '05 #5

P: n/a

"Li Fanxi" <li*****@163.com> wrote in message news:43**************************@posting.google.c om...
Because float is not an accurate data type.
It pains me when people say this. It leads people to believe that there is some
non-deterministic thing going on with floats. They're perfectly accurate. The issue
is not all rational numbers are representable accurately. The confusing issue is that
while people understand that 1/3 isn't precisely representable in a finite precision
decimal, they don't undertand that .1 is NOT precisely representable in binary.
For example, an integer 1 add up for 1000 times, you get 1000, but if
you add float 0.1 for 1000 times, you may get 99.999, not 100.


..1 is converted to one of the two nearest representable float values which
is implementation specific. From then on, the result is deterministic. You
get 1000 * whatever the converted value is.
Jul 19 '05 #6

P: n/a
Ron Natalie wrote:
.1 is converted to one of the two nearest representable float values
which
is implementation specific. From then on, the result is
deterministic. You get 1000 * whatever the converted value is.


"1000 * whatever the converted value is" might also not be
representable.

Jul 19 '05 #7

P: n/a
"Ron Natalie" <ro*@sensor.com> wrote:

"Li Fanxi" <li*****@163.com> wrote in message news:43**************************@posting.google.c om...
Because float is not an accurate data type.


It pains me when people say this. It leads people to believe that there is some
non-deterministic thing going on with floats. They're perfectly accurate. The issue
is not all rational numbers are representable accurately. The confusing issue is that
while people understand that 1/3 isn't precisely representable in a finite precision
decimal, they don't undertand that .1 is NOT precisely representable in binary.


It's also true that floating point numbers are limited in their
precision. It will happily store a 45-digit number for you, but as
(maybe) 1.3456789 time 10 to the 45 power. Digits in excess of the
precision limit are (I think) lopped off with no error being
generated.

--
Tim Slattery
Sl********@bls.gov
Jul 19 '05 #8

P: n/a

"Tim Slattery" <Sl********@bls.gov> wrote in message news:md********************************@4ax.com...
It's also true that floating point numbers are limited in their
precision. It will happily store a 45-digit number for you, but as
(maybe) 1.3456789 time 10 to the 45 power. Digits in excess of the
precision limit are (I think) lopped off with no error being
generated.

If you're trying to equate decimal digits as some metric of precision you're
going to be disappointed.
Jul 19 '05 #9

P: n/a

"Ron Natalie"
If you're trying to equate decimal digits as some metric of precision you're going to be disappointed.


I've seen float described as having 7 digit precision and double has 15.

Fraser.
Jul 19 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.