473,508 Members | 2,441 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

static_cast<unsigned int> question...

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
9 7239
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


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

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

"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

"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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
17747
by: Anonymous | last post by:
Is there a non-brute force method of doing this? transform() looked likely but had no predefined function object. std::vector<double> src; std::vector<int> dest; ...
6
13234
by: bonham | last post by:
i m a beginner in C++. I have some questions: what is static_cast<unsigned>? i saw someone use static_cast<unsigned> and static_cast<unsigned char> together. why? e.g....
11
5624
by: Bo Peng | last post by:
Dear C++ experts, I need to store and retrieve a meta information that can be int or double. The program would be significantly simpler if I can handle two types uniformly. Right now, I am using...
0
7223
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7321
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7377
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7034
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
5045
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4702
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3191
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3179
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
412
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.