integer and floating point casts queries

C

c.lang.myself

hi,
I went through following program in a C puzzle book.

#include<stdio.h>

#define PR(x) printf("x=%.8g\t",(double)x);
#define NL putchar('\n');
#define PRINT4(x1,x2,x3,x4) PR(x1) PR(x2) PR(x3) PR(x4) NL

main()
{
double d;
float f;
long l;
int i;
i=l=f=d=100/3; PRINT4(i,l,f,d)
d=f=l=i=100/3; PRINT4(i,l,f,d)
i=l=f=d=100/3.; PRINT4(i,l,f,d)
d=f=l=i=(double)100/3; PRINT4(i,l,f,d)

i=l=f=d=(double)100000/3; PRINT4(i,l,f,d)
d=f=l=i=100000/3; PRINT4(i,l,f,d)
}


answer is also given there but i am not getting it.
Can some body please explain output of above program..
Please also explain % .8g format specifier....

thanks,
 
O

osmium

I went through following program in a C puzzle book.

#include<stdio.h>

#define PR(x) printf("x=%.8g\t",(double)x);
#define NL putchar('\n');
#define PRINT4(x1,x2,x3,x4) PR(x1) PR(x2) PR(x3) PR(x4) NL

main()
{
double d;
float f;
long l;
int i;
i=l=f=d=100/3; PRINT4(i,l,f,d)

Do you have a problem with these two satements? I note that there is an int
division.
Divide and conquer. ... Maybe.
 
H

Harald van Dijk

hi,
I went through following program in a C puzzle book.

#include<stdio.h>

#define PR(x) printf("x=%.8g\t",(double)x); #define NL putchar('\n');
#define PRINT4(x1,x2,x3,x4) PR(x1) PR(x2) PR(x3) PR(x4) NL

main()
{
double d;
float f;
long l;
int i;
i=l=f=d=100/3; PRINT4(i,l,f,d)
d=f=l=i=100/3; PRINT4(i,l,f,d)
i=l=f=d=100/3.; PRINT4(i,l,f,d)
d=f=l=i=(double)100/3; PRINT4(i,l,f,d)

i=l=f=d=(double)100000/3; PRINT4(i,l,f,d) d=f=l=i=100000/3;
PRINT4(i,l,f,d)
}


answer is also given there but i am not getting it. Can some body please
explain output of above program..

If the answer is given in the book, what part of it don't you get? There's
little point in any of us giving you the answer if you already state in
advance that you have read the answer, especially if you didn't get that.
Be precise. What does the book say? What about it is confusing?
Please also explain % .8g format
specifier....

This should be available from your system's documentation or any reference
book. I don't know if you read that already, and if so, if it didn't make
sense to you.

g means you want to print a floating-point number of type double, either
in the style of %e or %f (check your documentation/reference), depending
on the value. .8 here means you want to print at most 8 significant digits.
 
J

John Bode

hi,
I went through following program in a C puzzle book.

#include<stdio.h>

#define PR(x) printf("x=%.8g\t",(double)x);
#define NL putchar('\n');
#define PRINT4(x1,x2,x3,x4) PR(x1) PR(x2) PR(x3) PR(x4) NL

main()
{
    double d;
    float f;
    long l;
    int i;
    i=l=f=d=100/3;    PRINT4(i,l,f,d)
    d=f=l=i=100/3;    PRINT4(i,l,f,d)
    i=l=f=d=100/3.;    PRINT4(i,l,f,d)
    d=f=l=i=(double)100/3;    PRINT4(i,l,f,d)

    i=l=f=d=(double)100000/3;    PRINT4(i,l,f,d)
    d=f=l=i=100000/3;    PRINT4(i,l,f,d)

}

answer is also given there but i am not getting it.
Can some body please explain output of above program..

Some basics:

1. If both operands of the / operator are integer types, then the
result of the division is also an integer type; e.g., 5/2 == 2, 5/3 ==
1, 5/4 == 1, etc.

2. If the operands of the / operator are different types (for
example, float and int), then the value of the operand that is of
lower rank (shorter or less precise) is converted to the type of the
other operand before doing the division, and the result is the same
type as the operand of higher rank; e.g., int / long == long, int /
float == float, float / double == double, etc.

3. If the left hand side and the right hand side of the assignment
operator (=) are of different types, then the value of the right hand
side is converted to the type of the left hand side (modulo some
restrictions, such as that the target type must be wide enough able to
hold the converted value). If you're assigning an int value to a
double variable, the value will first be converted to double before
the assignment. Similarly, if you're trying to assign a double value
to an int variable, the value will be converted to an integer (by
truncating the fractional portion) before assignment.

4. The assignment operator is right-associative; that is, the
expression a=b=c is evaluated as a=(b=c); in other words, a is
assigned the result of b=c.

So let's look at the statement

i=l=f=d=100/3;

The expression 100/3 evaluates to an integer value, 33. This result
is first assigned to d. Since d is of type double, the integer value
33 is first converted to double (33.0). The result of d=100/3 (33.0)
is then assigned to f, converting the double value 33.0 to the float
value 33.0. This result (f=d=100/3) is then assigned to l, meaning
the float value 33.0 must first be converted to the long integer value
33. Finally, i is assigned the result of (l=f=d=100/3), after
converting the long value 33 to an int.

The second statement does pretty much the same thing, just changing
the order of assignment.

The third statement,

i=l=f=d=100/3.;

gives a different result because 3. is shorthand for 3.0, meaning that
3. is a floating-point value. Thus the result of 100/3. is
33.33333.... This is what gets assigned to d and f (taking the
conversions into account). l and i still get assigned 33, because
that's the result after converting the floating point value to an
integer.
Please also explain % .8g format specifier....

This is what your handy C reference manual is for. Basically, it
works the same as the f and e conversion specifiers, except that it
strips any trailing zeros, and if as a result there are no digits
after the decimal point, then the decimal point is stripped as well.
 
J

jameskuyper

John Bode wrote:
....
2. If the operands of the / operator are different types (for
example, float and int), then the value of the operand that is of
lower rank (shorter or less precise) is converted to the type of the
other operand before doing the division, and the result is the same
type as the operand of higher rank; e.g., int / long == long, int /
float == float, float / double == double, etc.

That's not quite the correct formulation. The standard does not rank
floating point types relative to integer types. The standard has a
separate rule for each floating point type, with the rule for the more
precise type taking precedence over the rule for the less precise
type. All three floating point rules take precedence over all of the
integer rules. The result is roughly equivalent to what would happen
if the rules for integer types were extended to include floating point
types, with all floating point types ranking above all floating point
types - but that's not the way the standard describes it.

In itself, that would be a minor quibble. However, a consequence of
this fact is that a floating point type could be less precise (at
least for sufficiently large values) than an integer type, yet (in
conflict with what you've said above) divisions between operands of
those types will still be carried out in the floating point type, not
the integer type. Take, for example, a 'float', and a 'long long'
whose value is much greater than 1.0/LDBL_EPSILON. For most
implementation that support 'long long', it can store such a value
much more precisely than 'float' can.
This is what your handy C reference manual is for. Basically, it
works the same as the f and e conversion specifiers, except that it
strips any trailing zeros, and if as a result there are no digits
after the decimal point, then the decimal point is stripped as well.

It can't work the same as both the f and the e specifiers, because for
many values those two specifiers work quite differently. The basic
idea of the g specifier is that it acts the same as EITHER the f OR
the e conversion specifier, whichever one allow display of greater
precision within the limits of the specified width (which defaults to
15). The actual specification of how it decides whether to imitate the
f or the e specifier is a little more complicated:

| Let P equal the precision if nonzero, 6 if the precision is omitted,
or
| 1 if the precision is zero. Then, if a conversion with style E would
| have an exponent of X:
| — if P > X >= -4, the conversion is with style f (or F) and
precision
| P - (X + 1).
| — otherwise, the conversion is with style e (or E) and precision P -
1.
 
M

Martin Ambuhl

hi,
I went through following program in a C puzzle book.


/* You might note that the following program has the same result as
your posted one, while avoiding the casts, avoided the problems
with implicit int declaration of main (legal only before C99), lack
of return value for main (with undefined results before C99), and
most use of macros.

If your implementation does not support 'inline' then add the line

#define inline

before the definition of printone().

I hope this somewhat cleaner version makes it easier for you to see
what's happening. */

#include <stdio.h>

inline void printone(double x)
{
printf("x=%.8g\t", x);
}

inline void printfour(double x1, double x2, double x3, double x4)
{
printone(x1);
printone(x2);
printone(x3);
printone(x4);
putchar('\n');
}

int main(void)
{
double d;
float f;
long l;
int i;
i = l = f = d = 100 / 3;
printfour(i, l, f, d);
d = f = l = i = 100 / 3;
printfour(i, l, f, d);
i = l = f = d = 100 / 3.;
printfour(i, l, f, d);
d = f = l = i = 100.0 / 3;
printfour(i, l, f, d);
i = l = f = d = 100000.0 / 3;
printfour(i, l, f, d);
d = f = l = i = 100000 / 3;
printfour(i, l, f, d);
return 0;
}
 
C

CBFalconer

John said:
.... snip ...


This is what your handy C reference manual is for. Basically, it
works the same as the f and e conversion specifiers, except that
it strips any trailing zeros, and if as a result there are no
digits after the decimal point, then the decimal point is
stripped as well.

Try section 7.19.6.1 in the C99 standard. I just keep n869.txt on
my system and can get to that section with a single command.

n869_txt.bz2 below is a bzip2 compressed version of n869.txt

Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://c-faq.com/> (C-faq)
<http://benpfaff.org/writings/clc/off-topic.html>
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf> (C99)
<http://cbfalconer.home.att.net/download/n869_txt.bz2> (pre-C99)
<http://www.dinkumware.com/c99.aspx> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
<http://clc-wiki.net/wiki/C_community:comp.lang.c:Introduction>
 
G

Guest

On Mon, 8 Dec 2008 10:29:42 -0800 (PST), "(e-mail address removed)"


Burn the book.


Yep, burn the book.


Actually, I've changed my mind.  Shred the book, then burn the
confetti.

in other words, heavy use of macros (#defines) tends to obscure
code. Sometimes macros are worth it but macros like this have
no place in a beginners book.


int main (void)

return 0;
And send a complaint to the author(s).

it's really bad code
 
J

James Kuyper

in other words, heavy use of macros (#defines) tends to obscure
code. Sometimes macros are worth it but macros like this have
no place in a beginners book.



int main (void)


return 0;


it's really bad code

Please remember he called this a "puzzle book". I suspect that it is NOT
intended for beginners, and not intended to be representative of good
programming practice. I would imagine that it's meant as a test of how
well you understand obscure features of C, and that most of the code
probably looks like IOCCC entries.
 
J

Joachim Schmitz

<deleted url to copyrighted material>
Please find e-book from which I posted the question in rapidshare link
given above...

I guess this copyright violation should be reported to Prentice Hall, for
them to take legal action...

Bye, Jojo
 
J

Joachim Schmitz

Richard said:
Joachim Schmitz said:


Feel free. The contact is greg_doench at prenhall dot com and yes,
they do take legal action to curtail breaches of copyright law.

done
 
C

c.lang.myself


I am a student. I did not thought about copyright. I apologize to
everybody. I just thought of helping everybody.
I am terrified to post again.
Bye,
 
K

Keith Thompson

I am a student. I did not thought about copyright. I apologize to
everybody. I just thought of helping everybody.
I am terrified to post again.

The owner of the web site hosting the pirated copy is likely to be in
trouble. You are not. Posting a URL for an illegal site is not a
good thing to do, but I don't believe it's illegal. And I doubt that
Joachim Schmitz mentioned your name in his message to prenhall.com.

Caveat: I am not a lawyer, so don't assume I'm correct on any legal
issues.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,076
Latest member
OrderKetoBeez

Latest Threads

Top