Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > static_cast<unsigned int> question...

Reply
Thread Tools

static_cast<unsigned int> question...

 
 
GuineaPig
Guest
Posts: n/a
 
      11-14-2003
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


 
Reply With Quote
 
 
 
 
Fraser Ross
Guest
Posts: n/a
 
      11-14-2003
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.


 
Reply With Quote
 
 
 
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      11-14-2003


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
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Peter van Merkerk
Guest
Posts: n/a
 
      11-14-2003
> 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



 
Reply With Quote
 
Li Fanxi
Guest
Posts: n/a
 
      11-14-2003
GuineaPig <(E-Mail Removed)> wrote in message news:<bp2gdq$19e$(E-Mail Removed)>...
> 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.
 
Reply With Quote
 
Ron Natalie
Guest
Posts: n/a
 
      11-14-2003

"Li Fanxi" <(E-Mail Removed)> wrote in message news:(E-Mail Removed) 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.


 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      11-14-2003
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.

 
Reply With Quote
 
Tim Slattery
Guest
Posts: n/a
 
      11-14-2003
"Ron Natalie" <(E-Mail Removed)> wrote:

>
>"Li Fanxi" <(E-Mail Removed)> wrote in message news:(E-Mail Removed) 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
(E-Mail Removed)
 
Reply With Quote
 
Ron Natalie
Guest
Posts: n/a
 
      11-14-2003

"Tim Slattery" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...

> 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.


 
Reply With Quote
 
Fraser Ross
Guest
Posts: n/a
 
      11-15-2003

"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.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments