473,385 Members | 2,180 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Float to int type casting?

Hi,

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);
5 printf("%d\n", *(int *)&a);
6 return 0;
7 }

The output is:

0
1099694080

I could not understand why the first printf prints 0 and the other
,1099694080...

I think there is sth different from simple type casting.Is it an
undefined behaviour?
Please let me understand.

Regards.

Feb 5 '06 #1
16 12759
Enekajmer wrote:
Hi,

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);
Here you're trying to print a float value with a conversion specifier
for int. The results are undefined.
5 printf("%d\n", *(int *)&a);
Here, you're reinterpreting the representation of the float. The results
are implementation defined.
6 return 0;
7 }

The output is:

0
1099694080

I could not understand why the first printf prints 0 and the other
,1099694080...

I think there is sth different from simple type casting.Is it an
undefined behaviour?


[the word is `something']

See above.

HTH,
--ag
--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
Feb 5 '06 #2

Artie Gold wrote:
Enekajmer wrote:
Hi,

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);


Here you're trying to print a float value with a conversion specifier
for int. The results are undefined.
5 printf("%d\n", *(int *)&a);


Here, you're reinterpreting the representation of the float. The results
are implementation defined.
6 return 0;
7 }

The output is:

0
1099694080

I could not understand why the first printf prints 0 and the other
,1099694080...

I think there is sth different from simple type casting.Is it an
undefined behaviour?


[the word is `something']

See above.

HTH,
--ag
--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"


Thanks i learnt the types of behaviours but i want to learn causes in
more details.To give an example, there is no problem for the snippet
code below:
....
float a=17.5;
int b=a; (type casting from float to int)
printf("b-->%d",b); // as normally, this prints "b-->17"
....

according to this example i guessed the output of the code below as 17
too before i compiled. As contrast its output is 0...

printf("a-->%d",a) //a is in float type
So, what are the causes of this case?The IEEE-754?

Regards.

Feb 5 '06 #3

"Artie Gold" <ar*******@austin.rr.com> wrote in message
news:44************@individual.net...
Enekajmer wrote:
Hi,

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);


Here you're trying to print a float value with a conversion specifier
for int. The results are undefined.


Actually, you're trying to print a double value, because the float is
promoted when it's not governed by a formal parameter in a prototype.

If it weren't for that, you'd probably get the same output from both
printfs.

--
RSH
Feb 5 '06 #4
Enekajmer wrote:
Thanks i learnt the types of behaviours but i want to learn causes in
more details.To give an example, there is no problem for the snippet
code below:
...
float a=17.5;
int b=a; (type casting from float to int)
This is, as you rightly say, a cast. It /converts/ a float value in `a`
to it's closest representation as int. Hence, (int)17.5 == 17.
printf("b-->%d",b); // as normally, this prints "b-->17"
...

according to this example i guessed the output of the code below as 17
too before i compiled. As contrast its output is 0...

printf("a-->%d",a) //a is in float type
Artie led you off the track here by saying "conversion specifier". A s a
matter of fact "%d" is a "format specifier". It tells printf()
to /interpret/ whatever is stored in a corresponding parameter (in your
case `a`) as an int. This means that printf() blindly takes whatever is
the bit representation of `a` and interprets these bits as if they were
an `int`. Them actually being an `float` the result is undefined. In
your case, it happened to be 0, but the effect could have been much
worse. Beware the Undefined behaviour monster -- it may make demons
come out of your nose! ;-)
So, what are the causes of this case?The IEEE-754?


No, see paragraph above...

Cheers

Vladimir

--
To invent, you need a good imagination and a pile of junk.
-- Thomas Edison

Feb 5 '06 #5
On 2006-02-05, Enekajmer <en*******@gmail.com> wrote:
Hi,

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);
5 printf("%d\n", *(int *)&a);
6 return 0;
7 }

The output is:

0
1099694080

I could not understand why the first printf prints 0 and the other
,1099694080...

I think there is sth different from simple type casting.Is it an
undefined behaviour?
Yes. Both printf lines invoke undefined behavior.
Please let me understand.


hint: a is promoted to a double when passed to printf as a float.
Feb 5 '06 #6
Vladimir S. Oka wrote:
Enekajmer wrote:
Thanks i learnt the types of behaviours but i want to learn causes in
more details.To give an example, there is no problem for the snippet
code below:
...
float a=17.5;
int b=a; (type casting from float to int)

This is, as you rightly say, a cast. It /converts/ a float value in `a`
to it's closest representation as int. Hence, (int)17.5 == 17.

printf("b-->%d",b); // as normally, this prints "b-->17"
...

according to this example i guessed the output of the code below as 17
too before i compiled. As contrast its output is 0...

printf("a-->%d",a) //a is in float type

Artie led you off the track here by saying "conversion specifier". A s a
matter of fact "%d" is a "format specifier". It tells printf()


A slip of the fingers. Thanks for the correction.
--ag to /interpret/ whatever is stored in a corresponding parameter (in your
case `a`) as an int. This means that printf() blindly takes whatever is
the bit representation of `a` and interprets these bits as if they were
an `int`. Them actually being an `float` the result is undefined. In
your case, it happened to be 0, but the effect could have been much
worse. Beware the Undefined behaviour monster -- it may make demons
come out of your nose! ;-)

So, what are the causes of this case?The IEEE-754?

No, see paragraph above...

Cheers

Vladimir

--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com (new post 8/5)
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
Feb 5 '06 #7
Robin Haigh wrote:
"Artie Gold" <ar*******@austin.rr.com> wrote in message
Enekajmer wrote:

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);


Here you're trying to print a float value with a conversion specifier
for int. The results are undefined.


Actually, you're trying to print a double value, because the float is
promoted when it's not governed by a formal parameter in a prototype.

If it weren't for that, you'd probably get the same output from both
printfs.


It's even worse than that - he is using a variadic function without
a prototype, which makes everything undefined behaviour.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Feb 5 '06 #8
Vladimir S. Oka wrote:
Enekajmer wrote:
Thanks i learnt the types of behaviours but i want to learn causes in
more details.To give an example, there is no problem for the snippet
code below:
...
float a=17.5;
int b=a; (type casting from float to int)


This is, as you rightly say, a cast. It /converts/ a float value in `a`
to it's closest representation as int. Hence, (int)17.5 == 17.


No, it's not a cast. It is, on the other hand, a conversion.
printf("b-->%d",b); // as normally, this prints "b-->17"
...

according to this example i guessed the output of the code below as 17
too before i compiled. As contrast its output is 0...

printf("a-->%d",a) //a is in float type


Artie led you off the track here by saying "conversion specifier". A s a
matter of fact "%d" is a "format specifier". It tells printf()
to /interpret/ whatever is stored in a corresponding parameter (in your
case `a`) as an int. This means that printf() blindly takes whatever is
the bit representation of `a` and interprets these bits as if they were
an `int`. Them actually being an `float` the result is undefined. In
your case, it happened to be 0, but the effect could have been much
worse. Beware the Undefined behaviour monster -- it may make demons
come out of your nose! ;-)


Actually, it does not take the bit pattern and reinterpret it. It
assumes that the parameter is an int and tries to read that and this is
undefined behaviour (i.e. anything can happen) because the standard says
it is.

There are calling conventions where even varargs parameters are passed
in appropriate registers, so in this case it could read whatever the
first integer register happens to contain which could have absolutely
nothing to do with the contents of a. The specific implementation I'm
thinking of (a real one) can actually cause even more fun. If the
parameter is a double it gets passed in a floating point register, but
also converted to an int and passed in an integer register, so you would
actually get the result the OP expected. However, when you pass an int
that is *only* passed in an integer register, so if you try to print an
int using the format specifier for a double, it will try to print
whatever happened to be in the floating point register.

The implementation happens to be the latest version of Visual Studio
when given appropriate options.

The moral of this is *never* try to say what C implementations do when
you invoke undefined behaviour, for it's ways are stranger than your
imagination can conceive.

It is reasonable to wonder why something is undefined, and sometimes
useful to know how undefined behaviour can manifest, but only if you
accept that literally *anything* can cause a different behaviour,
including it deciding to show a picture of your boss in the nude.
So, what are the causes of this case?The IEEE-754?


No, see paragraph above...


Indeed.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Feb 5 '06 #9
On Sun, 05 Feb 2006 11:16:49 -0600, Artie Gold
<ar*******@austin.rr.com> wrote in comp.lang.c:
Enekajmer wrote:
Hi,

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);


Here you're trying to print a float value with a conversion specifier
for int. The results are undefined.
5 printf("%d\n", *(int *)&a);


Here, you're reinterpreting the representation of the float. The results
are implementation defined.


[snip]

No, undefined. There are only two defined ways to look at the bits of
an object of type float, those are using an lvalue of type float, or
using an array of unsigned characters the size of a float.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Feb 5 '06 #10
On Sun, 5 Feb 2006 19:27:51 +0000 (UTC), "Vladimir S. Oka"
<no****@btopenworld.com> wrote in comp.lang.c:
Enekajmer wrote:
Thanks i learnt the types of behaviours but i want to learn causes in
more details.To give an example, there is no problem for the snippet
code below:
...
float a=17.5;
int b=a; (type casting from float to int)


This is, as you rightly say, a cast. It /converts/ a float value in `a`
to it's closest representation as int. Hence, (int)17.5 == 17.
printf("b-->%d",b); // as normally, this prints "b-->17"
...

according to this example i guessed the output of the code below as 17
too before i compiled. As contrast its output is 0...

printf("a-->%d",a) //a is in float type


Artie led you off the track here by saying "conversion specifier". A s a
matter of fact "%d" is a "format specifier". It tells printf()


[snip]

Actually, Artie was mostly correct. Here's some exact wording copied
from the C standard, paragraphs 3 and of "7.19.6.1 The fprintf
function":

====
3 The format shall be a multibyte character sequence, beginning and
ending in its initial shift state. The format is composed of zero or
more directives: ordinary multibyte characters (not %), which are
copied unchanged to the output stream; and conversion specifications,
each of which results in fetching zero or more subsequent arguments,
converting them, if applicable, according to the corresponding
conversion specifier, and then writing the result to the output
stream.

4 Each conversion specification is introduced by the character %.
After the %, the following appear in sequence:

— Zero or more flags (in any order) that modify the meaning of the
conversion specification.

— An optional minimum field width. If the converted value has fewer
characters than the field width, it is padded with spaces (by default)
on the left (or right, if the left adjustment flag, described later,
has been given) to the field width. The field width takes the form of
an asterisk * (described later) or a decimal integer.

— An optional precision that gives the minimum number of digits to
appear for the d, i, o, u, x, and X conversions, the number of digits
to appear after the decimal-point character for a, A, e, E, f, and F
conversions, the maximum number of significant digits for the g and G
conversions, or the maximum number of bytes to be written for s
conversions. The precision takes the form of a period (.) followed
either by an asterisk * (described later) or by an optional decimal
integer; if only the period is specified, the precision is taken as
zero. If a precision appears with any other conversion specifier, the
behavior is undefined.

— An optional length modifier that specifies the size of the argument.

— A conversion specifier character that specifies the type of
conversion to be applied.
====

Notice specifically the final sentence of paragraph 4.

In C standard terminology, "%d" is a "conversion specification" of
which the 'd' is the conversion specifier.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Feb 5 '06 #11
"Vladimir S. Oka" <no****@btopenworld.com> writes:
Enekajmer wrote:
Thanks i learnt the types of behaviours but i want to learn causes in
more details.To give an example, there is no problem for the snippet
code below:
...
float a=17.5;
int b=a; (type casting from float to int)


This is, as you rightly say, a cast. It /converts/ a float value in `a`
to it's closest representation as int. Hence, (int)17.5 == 17.

[...]

No, it's not a cast. A cast is an explicit unary operator consisting
of a type name in parentheses; it specifies a conversion. So:

int b = a;

involves a conversion, but no cast, whereas

int b = (int)a;

has a cast that specifies the same conversion. (Thus the phrase
"implicit cast" is meaningless.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 5 '06 #12
Jack Klein wrote:
On Sun, 5 Feb 2006 19:27:51 +0000 (UTC), "Vladimir S. Oka"
<no****@btopenworld.com> wrote in comp.lang.c:
Enekajmer wrote:
> Thanks i learnt the types of behaviours but i want to learn causes
> in more details.To give an example, there is no problem for the
> snippet code below:
> ...
> float a=17.5;
> int b=a; (type casting from float to int)
This is, as you rightly say, a cast. It /converts/ a float value in
`a` to it's closest representation as int. Hence, (int)17.5 == 17.
> printf("b-->%d",b); // as normally, this prints "b-->17"
> ...
>
> according to this example i guessed the output of the code below as
> 17 too before i compiled. As contrast its output is 0...
>
> printf("a-->%d",a) //a is in float type


Artie led you off the track here by saying "conversion specifier". A
s a matter of fact "%d" is a "format specifier". It tells printf()


[snip]

Actually, Artie was mostly correct. Here's some exact wording copied
from the C standard, paragraphs 3 and of "7.19.6.1 The fprintf
function":


<snip C&V>
Β— A conversion specifier character that specifies the type of
conversion to be applied.
====

Notice specifically the final sentence of paragraph 4.

In C standard terminology, "%d" is a "conversion specification" of
which the 'd' is the conversion specifier.


I stand corrected, apologies where due. I guess too much FORTRAN at some
point is to blame. ;-)

I still feel that "conversion" can be misleading, as some may expect
that the parameter values will be /converted/ to what one specifies as
their display format. This was, IMHO, clearly what confused the OP.
But, who's to argue with the Gospel. ;-)
--
BR, Vladimir

Garbage In -- Gospel Out.

Feb 6 '06 #13
Keith Thompson wrote:
"Vladimir S. Oka" <no****@btopenworld.com> writes:
Enekajmer wrote:
Thanks i learnt the types of behaviours but i want to learn causes
in more details.To give an example, there is no problem for the
snippet code below:
...
float a=17.5;
int b=a; (type casting from float to int)


This is, as you rightly say, a cast. It /converts/ a float value in
`a` to it's closest representation as int. Hence, (int)17.5 == 17.

[...]

No, it's not a cast. A cast is an explicit unary operator consisting
of a type name in parentheses; it specifies a conversion. So:

int b = a;

involves a conversion, but no cast, whereas

int b = (int)a;

has a cast that specifies the same conversion. (Thus the phrase
"implicit cast" is meaningless.)


You are absolutely right.

I can't really explain this, apart maybe by the fact that I had the
example I put at the very end (which was meant to say something
different) in my mind too early in writing the whole thing. This
possibly also explains the conversion bit I was talking about in the
middle. Quite a mess, really... :-(
--
BR, Vladimir

Electrocution, n.:
Burning at the stake with all the modern improvements.

Feb 6 '06 #14
Jack Klein <ja*******@spamcop.net> writes:
On Sun, 5 Feb 2006 19:27:51 +0000 (UTC), "Vladimir S. Oka"
<no****@btopenworld.com> wrote in comp.lang.c: [...]
Artie led you off the track here by saying "conversion specifier". A s a
matter of fact "%d" is a "format specifier". It tells printf()


[snip]

Actually, Artie was mostly correct. Here's some exact wording copied
from the C standard, paragraphs 3 and of "7.19.6.1 The fprintf
function":

[snip] Notice specifically the final sentence of paragraph 4.

In C standard terminology, "%d" is a "conversion specification" of
which the 'd' is the conversion specifier.


And, just to be clear, the standard's use of the phrase "conversion
specification" does not refer to the same kind of "conversion"
discussed in section 6.3 of the standard (such as the conversion
implied by a cast expression), though it's loosely similar.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 6 '06 #15

Enekajmer wrote:
Hi,

1 int main()
2 {
3 float a = 17.5;
4 printf("%d\n", a);
This is not a cast. If you use the %d specifier, printf expects the
corresponding argument to be of type int. a is not type int, so the
behavior is undefined. Since it's undefined, there's no point in
trying to explain *why* it prints 0 instead of some other value.
5 printf("%d\n", *(int *)&a);
This is a cast, but it isn't doing what you think it is. This tells
printf to interpret the bit pattern in a *as if* it were an int; it
does not convert the value of a to the integer equivalent. To do that,
you would write

printf("%d\n", (int) a);

Integer and floating-point types usually have completely different
representations. One reasonable hypothetical 32-bit representation for
17.5 would be

00111101100011000000000000000000

or

0x3d8c0000

where bit 31 is the sign bit, bits 30-23 are the exponent, and bits
22-0 are the mantissa, which represents values in the range [0.5-1).
The above bit string represents +0.546875 * 2^5 == 17.5 in this format.
Compare this to a two's complement, 32-bit, signed integer
representation of 17:

00000000000000000000000000010001

or

0x00000011

Hopefully you can see why line 5 gave you such an obnoxious number. It
was taking the bit string representing 17.5 in your machine's floating
point format (0x418c0000) and interpreting it as an int, instead of
*converting* that value to the int equivalent (0x00000011).
6 return 0;
7 }

The output is:

0
1099694080

I could not understand why the first printf prints 0 and the other
,1099694080...

I think there is sth different from simple type casting.Is it an
undefined behaviour?
Please let me understand.

Regards.


Feb 6 '06 #16
"Enekajmer" <en*******@gmail.com> wrote:
# Hi,
#
# 1 int main()
# 2 {
# 3 float a = 17.5;
# 4 printf("%d\n", a);
# 5 printf("%d\n", *(int *)&a);

(int)a is sufficient, and will also work if you
cannot take the address of a.

# 6 return 0;
# 7 }
#
# The output is:
#
# 0
# 1099694080
#
# I could not understand why the first printf prints 0 and the other
# ,1099694080...

The language does not require the types of arguments be
made available from the caller to callee. If you prototype
a function, the compiler can check the prototype against
the call and cast to type, but a varargs list cannot be
prototyped and therefore cannot be generally checked. The
caller makes a collection of bytes of available and assumes
the callee interprets those bytes in the same manner as the
caller does.

In the first case the caller is making the bytes of a double
available but callee is looking for the bytes of an int.
Wackiness ensues.

In the second case both caller and callee agree the bytes
are an int.

In printf and related functions, the callee deduces argument
types from the format string. Some compilers make guesses
about what they know of the callee to warn of argument mismatches,
but that is not generally possible with the current state of
C.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Mention something out of a Charleton Heston movie, and suddenly
everybody's a theology scholar.
Feb 6 '06 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: maxim vexler | last post by:
in a book i am ready now : O'Reilly - Web Database Application with PHP and MySQL, 2nd ed. by David Lane, Hugh E. Williams on chapter 9 the author give an example for age validation :...
3
by: Cgacc20 | last post by:
I have a c struct from old code that cannot be modified and I am trying to write a wrapper C++ class around it. This class is often passed as a pointer to some c functions of a library and I...
5
by: Suzanne Vogel | last post by:
** Isn't the 'static_cast' operator the same as traditional type casting? ie, Aren't the following ways of getting b1, b2 the same? // 'Derived' is derived from 'Base' Derived* d = new...
1
by: JohnK | last post by:
under the covers is type casting in VB.Net the same as C# ? myObject = CType(..,..) in VB.Net vs myObject = (SomeClass)aObject
1
by: chook | last post by:
Wherein differences between type casting in C++ : static_cast, dinamic_cast, reinterpret_cast, const_cast and C type casting, like xxx = (type)yyy; What, when and why is necessary to use?
9
by: Roman Mashak | last post by:
Hello, All! Given the sample piece of code I have: #include <stdio.h> #include <string.h> int main(void) { short int i, j;
23
by: Renι Nordby | last post by:
Hi there, Is there anyone that knows how to do the following? I have a class A and a class B, that 100% inherits from class A (this means that I don't have other code in class B, than...
7
by: Ben R. | last post by:
How does automatic type casting happen in vb.net? I notice that databinder.eval "uses reflectoin" to find out the type it's dealing with. Does vb.net do the same thing behind the scenes when an...
11
by: Frederic Rentsch | last post by:
Hi all, If I derive a class from another one because I need a few extra features, is there a way to promote the base class to the derived one without having to make copies of all attributes? ...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.