printf("%d",1.0/3*3) 
Author Message
 printf("%d",1.0/3*3)

Dear all,
     I have encountered this problem:
         printf("%d",1.0/3*3);  //the output is 0, not 1.
     but if like this:
         int a=1.0/3*3;
         printf("%d",a);   //the output is 1.

I don't know why, anyone has any idea?
Thanks in advance.



Tue, 06 Dec 2005 00:13:12 GMT  
 printf("%d",1.0/3*3)


Quote:
>Dear all,
>     I have encountered this problem:
>         printf("%d",1.0/3*3);  //the output is 0, not 1.

Well, you lie to printf()

You told it to expect an integer value (the "%d" formatting option), but you
/gave/ it a double precision floatingpoint value (the 1.0/3*3)

Of course it's not going to print value you expect. You caused it to invoke
"undefined behaviour", and as such, it can print anything it wants.

Quote:
>     but if like this:
>         int a=1.0/3*3;
>         printf("%d",a);   //the output is 1.

Here, you both tell printf() to expect an integer value (the "%d" formatter),
and /give/ it an integer value (the int a;)

Quote:
>I don't know why, anyone has any idea?
>Thanks in advance.

Lew Pitcher
IT Consultant, Enterprise Technology Solutions
Toronto Dominion Bank Financial Group

(Opinions expressed are my own, not my employers')



Tue, 06 Dec 2005 00:30:37 GMT  
 printf("%d",1.0/3*3)

Quote:

> Dear all,
>      I have encountered this problem:
>          printf("%d",1.0/3*3);  //the output is 0, not 1.

FLOATs should be printed using %f format.


Tue, 06 Dec 2005 00:44:03 GMT  
 printf("%d",1.0/3*3)

Quote:
> Dear all,
>      I have encountered this problem:
>          printf("%d",1.0/3*3);  file://the output is 0, not 1.

It could be anything else as well.  The expression
1.0/3*3 has type 'double'.  Passing an argument other
than of type 'int' for a '%d' specifier produces
'undefined behavior'.  IF you want to printf() a
floating point value, use %f

Quote:
>      but if like this:
>          int a=1.0/3*3;

The value of the type 'double' expression
1.0/3*3 is 1.0.  The initialization of the
type 'int' object 'a' with this value converts
it to type 'int', giving it a value of 1.

Also note that if the value of the initialization
expression had any fractional part, it would be
discarded.  So it's not a good idea to try to
initialize an int with a floating point expression.

int a = 5.0 / 10; /* 'a' will have a value of zero */

Quote:
>          printf("%d",a);   file://the output is 1.

As expected.  '%d' is the specifier for type 'int',
so all is well.

In short, the '%' specifiers do not perform any
conversions, they simply tell 'printf()' what the
corresponding argument type is.  So if you give
mismatched specifiers and arguments, of course
'printf()' can't know that you 'lied'.  Hence
this situation is designated to produce 'undefined
behavior.'

-Mike



Tue, 06 Dec 2005 01:10:15 GMT  
 printf("%d",1.0/3*3)
Thank you , Mike.
I know this unmatched datatype here, and I just want to know why %d here
result in 0. (You say this is an undefined behavior).  for example:

 float test=1.00f;
 printf("%d\n",test);

here,  I debug these codes:  I find the address of "test" (eg.  &test),
then, I get the 4 bytes of "test":  00 00 80 3F
if we convert them to a float variable, it is 1.0000
if we convert these 4 bytes to an int variable, it should be 16256, not 0!
that is to say, I think it is like this:
   float test=1.00f;
   int  a;
    memcpy(&a,&test,4);
   printf("%d\n",a);

Quote:
> > Dear all,
> >      I have encountered this problem:
> >          printf("%d",1.0/3*3);  file://the output is 0, not 1.

> It could be anything else as well.  The expression
> 1.0/3*3 has type 'double'.  Passing an argument other
> than of type 'int' for a '%d' specifier produces
> 'undefined behavior'.  IF you want to printf() a
> floating point value, use %f

> >      but if like this:
> >          int a=1.0/3*3;

> The value of the type 'double' expression
> 1.0/3*3 is 1.0.  The initialization of the
> type 'int' object 'a' with this value converts
> it to type 'int', giving it a value of 1.

> Also note that if the value of the initialization
> expression had any fractional part, it would be
> discarded.  So it's not a good idea to try to
> initialize an int with a floating point expression.

> int a = 5.0 / 10; /* 'a' will have a value of zero */

> >          printf("%d",a);   file://the output is 1.

> As expected.  '%d' is the specifier for type 'int',
> so all is well.

> In short, the '%' specifiers do not perform any
> conversions, they simply tell 'printf()' what the
> corresponding argument type is.  So if you give
> mismatched specifiers and arguments, of course
> 'printf()' can't know that you 'lied'.  Hence
> this situation is designated to produce 'undefined
> behavior.'

> -Mike



Tue, 06 Dec 2005 02:04:51 GMT  
 printf("%d",1.0/3*3)


Quote:
>Thank you , Mike.
>I know this unmatched datatype here, and I just want to know why %d here
>result in 0. (You say this is an undefined behavior).  for example:

> float test=1.00f;
> printf("%d\n",test);

>here,  I debug these codes:  I find the address of "test" (eg.  &test),
>then, I get the 4 bytes of "test":  00 00 80 3F
>if we convert them to a float variable, it is 1.0000
>if we convert these 4 bytes to an int variable, it should be 16256, not 0!

Assuming that
a) sizeof(int) == 4, and CHAR_BIT == 8, and
b) you are dealing with a "big endian" word.

OTOH, assuming that sizeof(int) == 2 and CHAR_BIT == 8, then your four bytes of
float (0x0000803F) are interpreted as 0x000000 and show up as a zero.

--
Lew Pitcher
IT Consultant, Enterprise Technology Solutions
Toronto Dominion Bank Financial Group

(Opinions expressed are my own, not my employers')



Tue, 06 Dec 2005 02:09:35 GMT  
 printf("%d",1.0/3*3)

Quote:
> Thank you , Mike.
> I know this unmatched datatype here,

You know it's wrong but you do it anyway?  Huh?

Quote:
>and I just want to know why %d here
> result in 0.

Because it does.  The behavior is *undefined*.  IOW,
the result could be output of 7437238932, the square
root of infinity, nothing at all, etc.  Look up 'nasal
demons' (and stock up on antihistamines. :-) )

You're violating a language requirement, so your
program's behavior is outside its definition.
*Anything* is allowed to happen.

Quote:
> (You say this is an undefined behavior).

Yes.  Do you understand what that means?

Quote:
>for example:

>  float test=1.00f;
>  printf("%d\n",test);

This theoretically could cause Iraq to invade Utah.

Quote:

> here,  I debug these codes:

There's no point in 'debugging' something which has
no definition for its behavior.

Quote:
>I find the address of "test" (eg.  &test),
> then, I get the 4 bytes of "test":

Why do you think 'test' occupies four bytes?  It might,
it might not. THe only guaranteed way to determine the
size of an object (other than the 'char' types, which have
size 1 by definition), is with the 'sizeof' operator:

    sizeof test

Quote:
>00 00 80 3F

The language has nothing to say about the internal
representation of a float.  That might or might not
be a valid representation on some systems.

Quote:
> if we convert them to a float variable, it is 1.0000

It might be on some platforms, but the language is silent
about this.  It's not defined.

Quote:
> if we convert these 4 bytes to an int variable,

The result could be one of several possible values,
depending upon your host architechture.  It might
even be a 'trap representation'.

Quote:
>it should be 16256, not 0!

It might on some systems, on others it might be e.g 42.

Quote:
> that is to say, I think it is like this:

You think incorrectly.

Quote:
>    float test=1.00f;
>    int  a;
>     memcpy(&a,&test,4);

There's no guarantee that type 'int' occupies four
bytes.  (The largest required value for type 'int'
only needs two bytes.) If it's smaller than four
bytes, you've written to memory your program does
not 'own'.  Undefined behavior.  Perhaps a different
demon from another province of Hades. :-)

Also, there's no reason to assume that the internal
representation of types 'int' and 'float' are the
same.  As a matter of fact, they cannot be.  After
that memcpy(), evaluation of 'a' will produce
undefined behavior.

Quote:
>    printf("%d\n",a);

Nasal demons.

If you're interested in exploring the interal
representation details of your platform, that's
not topical here.

IF you want to discuss the C language, note that
it does not define what you're asking about. It
only defines value ranges and behavior of objects
(and certain requirements for the representations
of integer types).

Your conception of what 'should' happen has no
bearing on what the language specification dictates.

What C textbooks are you using?

-Mike



Tue, 06 Dec 2005 02:45:49 GMT  
 printf("%d",1.0/3*3)

Quote:

>Thank you , Mike.
>I know this unmatched datatype here, and I just want to know why %d here
>result in 0. (You say this is an undefined behavior).  for example:

> float test=1.00f;
> printf("%d\n",test);

>here,  I debug these codes:  I find the address of "test" (eg.  &test),
>then, I get the 4 bytes of "test":  00 00 80 3F
>if we convert them to a float variable, it is 1.0000
>if we convert these 4 bytes to an int variable, it should be 16256, not 0!
>that is to say, I think it is like this:
>   float test=1.00f;
>   int  a;
>    memcpy(&a,&test,4);
>   printf("%d\n",a);

Obviously, it's not like that.  Which illustrates one of the risks of
trying to guess what behavior will result from undefined code.

Based on the fact that floats are promoted to doubles in this
situation, it is more likely that the compiler generated code that did
something like:
   float test=1.00f;
   double d;
   int a;
   d = test;
   memcpy(&a, &d, 4);
   printf("%d\n",a);

But undefined behivor is just that -- undefined.  All we're doing here
is speculating about what your compiler might have elected to do.

     -- Brett



Tue, 06 Dec 2005 03:51:48 GMT  
 printf("%d",1.0/3*3)
On Fri, 20 Jun 2003 02:04:51 +0800, "Zhiqiang Ye"

Quote:

>> >      but if like this:
>> >          int a=1.0/3*3;

>> The value of the type 'double' expression
>> 1.0/3*3 is 1.0.  The initialization of the
>> type 'int' object 'a' with this value converts
>> it to type 'int', giving it a value of 1.

If the compiler makes this

double z = (1.0/3)*3;
int a=(int)z;

Is there any guarantee that a==1?  Given that floats are inaccurate.
I could believe on some implementations a==0.

Jim



Tue, 06 Dec 2005 09:16:41 GMT  
 printf("%d",1.0/3*3)
Hi Zhiqiang,

Quote:
>     I have encountered this problem:
>         printf("%d",1.0/3*3);  //the output is 0, not 1.
>     but if like this:
>         int a=1.0/3*3; printf("%d",a);   //the output is 1.

You already gave the answer. On the first line, when you
say
        printf("%d",1.0/3*3);

The compiler computes the 1.0/3*3 and stores it in memory
as a Floating point number; since printf expects to read
an integer (%d) it treats that memory location as an integer
and shows the wrong result. On your second code segment
you store the value as an integer, and printf treats it
as an integer, and everything goes fine.

Altough integers and floats are both uses 4 bytes in memory,
their structure is highly different. When computer stores
an integer value, it uses the 31st bit as sign bit, and
the bits 0 to 30 to store the value; however, when computer
stores a floating point number it uses 31st bit as sign bit,
bits 30-23 as exponent, and bits 22-0 as significant. So even
the value is the same, both memory locations looks very different.

        int   x = 1;    (stored as 00 00 80 3f in memory)
        float y = 1;    (stored as 01 00 00 00 in memory)

(this may look different on your system, if your system uses
a different byte order)

For more information about floating point numbers, search
the net for IEEE 754.

Best regards, Ali Cinar

 \    / _ |_ |. _  _  Ali Cinar

 340 N. 12th Street - Philadelphia, PA 19107 - 215/925-1800



Tue, 06 Dec 2005 07:22:22 GMT  
 printf("%d",1.0/3*3)
Thank you all very much.
I understand this now  :)


Tue, 06 Dec 2005 14:10:04 GMT  
 printf("%d",1.0/3*3)
On Fri, 20 Jun 2003 11:16:41 +1000,

Quote:
>On Fri, 20 Jun 2003 02:04:51 +0800, "Zhiqiang Ye"

>>> >      but if like this:
>>> >          int a=1.0/3*3;

>>> The value of the type 'double' expression
>>> 1.0/3*3 is 1.0.  The initialization of the
>>> type 'int' object 'a' with this value converts
>>> it to type 'int', giving it a value of 1.

>If the compiler makes this

>double z = (1.0/3)*3;
>int a=(int)z;

>Is there any guarantee that a==1?  Given that floats are inaccurate.
>I could believe on some implementations a==0.

Try decimal arithmatic whith 5 decimals:

1.0/3 is 0.33333
0.33333*3 is 0.99999
0.99999 after discarding the fraction becomes 0

When converting from float to int there are alway certain valus where
a very tiny change in the floating point value will case a change of
1 in the integer value.

Villy



Tue, 06 Dec 2005 16:02:27 GMT  
 printf("%d",1.0/3*3)

Quote:

>You already gave the answer. On the first line, when you
>say
>        printf("%d",1.0/3*3);

>The compiler computes the 1.0/3*3 and stores it in memory
>as a Floating point number; since printf expects to read
>an integer (%d) it treats that memory location as an integer
>and shows the wrong result. On your second code segment
>you store the value as an integer, and printf treats it
>as an integer, and everything goes fine.

>Altough integers and floats are both uses 4 bytes in memory,
>their structure is highly different. When computer stores
>an integer value, it uses the 31st bit as sign bit, and
>the bits 0 to 30 to store the value; however, when computer
>stores a floating point number it uses 31st bit as sign bit,
>bits 30-23 as exponent, and bits 22-0 as significant. So even
>the value is the same, both memory locations looks very different.

>        int   x = 1;    (stored as 00 00 80 3f in memory)
>        float y = 1;    (stored as 01 00 00 00 in memory)

You got those backwarod (01 00 00 00 is the int; 00 00 80 3F is the
float).  And you also haven't explained why his code printed 0.  If it
worked as you suggest, then it should print the int that corresponds to
(00 00 80 3F).  Assuming the machine is also little-endian for
integers, it would be one-billion-and-something (not the
16-thousand-and-someting that the original poster said -- he had the
byte order wrong).  And even if it is big-endian, it still wouldnb't be
zero.

One explanation is that the machine has two byte ints, but that seems
unlikely.

The real explanation is probably that the float is promoted to a double
when it's passed as a parameter to printf; a double is eight bytes; on
a little endian machine, the first four are the least-signifigant four,
which, when storing 1.00, will all be 0, which is the representation of
an integer whose value is 0.

     -- Brett



Tue, 06 Dec 2005 20:09:11 GMT  
 printf("%d",1.0/3*3)
hi, Ali

Quote:
> Altough integers and floats are both uses 4 bytes in memory,
> their structure is highly different. When computer stores
> an integer value, it uses the 31st bit as sign bit, and
> the bits 0 to 30 to store the value; however, when computer
> stores a floating point number it uses 31st bit as sign bit,
> bits 30-23 as exponent, and bits 22-0 as significant. So even
> the value is the same, both memory locations looks very different.

>         int   x = 1;    (stored as 00 00 80 3f in memory)
>         float y = 1;    (stored as 01 00 00 00 in memory)

Maybe here is a typos, they should be like this:
         float x = 1;    (stored as 00 00 80 3f in memory)
         int   y = 1;    (stored as 01 00 00 00 in memory)

Yes, I understand your meaning. And my system is just like yours
and sizeof(int) and sizeof(float) are both 4 bytes:
int x=1 is stored as 01 00 00 00 in memory,
float y=1 is stored as 00 00 80 3f in memory.

If we treat 00 00 80 3f as float, it is 1.0000,
but if we treat 00 00 80 3f as integer, it is 1065353216, not zero......

but if we using  printf("%d",x); the results is zero, not 1065353216.....

Thank you for your patience  :)

Zhiqiang Ye



Tue, 06 Dec 2005 20:21:49 GMT  
 printf("%d",1.0/3*3)

Quote:

>a double is eight bytes

What I meant, of course, is that it is likely that a double is eight
bytes on this posters machine.  

     -- Brett



Tue, 06 Dec 2005 20:46:44 GMT  
 
 [ 18 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Behaviour of printf("[%.0g]",1.0)

2. printf("/033E")

3. printf("%g") to 3 sig figs

4. "implicit declaration of function printf"

5. "printf()" hangs machine

6. printf("%x",string_buffer); - Output question

7. C source code for "printf"

8. "printf" question

9. printf("%x",float) is ZERO??

10. printf("%")

11. how does printf("%#06x", 0x80) look?

12. Chapter and verse on printf("\n")

 

 
Powered by phpBB® Forum Software