(int/int) != int
Author Message
(int/int) != int

The following code simply does N O T make sense, check it out.

int  Numerator = 5;
int  Denominator = 2;
float  Result = 0;

Result = Numerator/Denominator;
printf("Result = %f\n", Result);      //Results 2 and not 2.5!!

You would think that C is smart enough to get this right, I mean if I divide
5/2 the answer is 2.5 not 2!! By this time you are ready to flame me and
tell me that this is proper behavior and that it has to do with the
automatic casting feature. All I have to say about that is that just because
it is proper behavior does not mean that is not stupid behavior.

1. - Is there any way to tell C to wise up and get it right without having
to do something like Result = (float)Numerator/(float)Denominator?
2. - Is there any way to tell C not to auto cast but to crash so that is
easy to find where the error is hiding?

Thank you.

Fri, 12 Dec 2003 10:29:08 GMT
(int/int) != int

Quote:
> The following code simply does N O T make sense, check it out.

> int  Numerator = 5;
>  int  Denominator = 2;
>  float  Result = 0;

>  Result = Numerator/Denominator;
>  printf("Result = %f\n", Result);      //Results 2 and not 2.5!!

> You would think that C is smart enough to get this right, I mean if I
divide
> 5/2 the answer is 2.5 not 2!! By this time you are ready to flame me and
> tell me that this is proper behavior and that it has to do with the
> automatic casting feature. All I have to say about that is that just
because
> it is proper behavior does not mean that is not stupid behavior.

You call it stupid.  I call it logical.  Read up the standards on variable
promotion.  int/int is an integer divide since both operands are integers.
it is only promoted to a float when it needs to be.

Tom

Fri, 12 Dec 2003 10:34:53 GMT
(int/int) != int

Quote:

> The following code simply does N O T make sense, check it out.

> int  Numerator = 5;
>  int  Denominator = 2;
>  float  Result = 0;

>  Result = Numerator/Denominator;
>  printf("Result = %f\n", Result);      //Results 2 and not 2.5!!

> You would think that C is smart enough to get this right, I mean if I divide
> 5/2 the answer is 2.5 not 2!! By this time you are ready to flame me and
> tell me that this is proper behavior and that it has to do with the
> automatic casting feature. All I have to say about that is that just because
> it is proper behavior does not mean that is not stupid behavior.

The phrase "automatic casting" grates on my ears.  A cast is
always something explicit; it is a way to do an end-run around
C's type system.  But what takes place above isn't anything like
that.  Rather, it's simply a conversion that takes place
automatically.

Quote:
> 1. - Is there any way to tell C to wise up and get it right without having
> to do something like Result = (float)Numerator/(float)Denominator?

Yes.  You can declare Numerator and Denominator as `float'
variables.  (`double' is probably a better choice, actually.)

Quote:
> 2. - Is there any way to tell C not to auto cast but to crash so that is
> easy to find where the error is hiding?

No.

Quote:

Yes.  Arithmetic operations on integers produce integer results.
This is very common behavior among programming languages and in
fact seasoned programmers are often surprised when they encounter
languages that don't have this behavior (e.g., Perl).
--
"What is appropriate for the master is not appropriate for the novice.
You must understand the Tao before transcending structure."
--The Tao of Programming

Fri, 12 Dec 2003 10:34:13 GMT
(int/int) != int

Quote:
> The following code simply does N O T make sense, check it out.

> int  Numerator = 5;
>  int  Denominator = 2;
>  float  Result = 0;

>  Result = Numerator/Denominator;
>  printf("Result = %f\n", Result);      file://Results 2 and not 2.5!!

> You would think that C is smart enough to get this right, I mean if I
divide
> 5/2 the answer is 2.5 not 2!! By this time you are ready to flame me and

~ Quick Computer Science Lesson ~

Most computers only support mathematical operations in which both operands
are of the same type. The result is usually the same type. (Sometimes
expanded to a larger register to fit). So given that the default behavior of
most computers echoes exactly the behavior of C, I would say it is not
"stupid" at all.

If you are implying that C should automatically convert all integer operands
in an expression to floating-point so that you may be spared the terribly
difficult work of using a cast (or better yet, using appropriate types in
the first place), then I would say that is a little shortsighted. Especially
when you consider some computers do not have any native floating-point
instructions at all.

Keep in mind that C is *not* a mathematical programming language, nor was it
ever intended to be.

-Daniel

Fri, 12 Dec 2003 10:56:49 GMT
(int/int) != int

Quote:
> You call it stupid.  I call it logical.

5/2 = 2? Is this logical? Not to me, not at all. Just because you accept
what the standard says it still does not make it a logical result. The
standard could very well have stated that 5/2 = 2.5.

Fri, 12 Dec 2003 11:11:11 GMT
(int/int) != int

Quote:
> (or better yet, using appropriate types in the first place)

The only values that were intended to go in the int variables were int
values, the result was not intende to be int, why would it be wrong?

Fri, 12 Dec 2003 11:20:06 GMT
(int/int) != int

Quote:

> The following code simply does N O T make sense, check it out.

> int  Numerator = 5;
>  int  Denominator = 2;
>  float  Result = 0;

>  Result = Numerator/Denominator;
>  printf("Result = %f\n", Result);      //Results 2 and not 2.5!!

> You would think that C is smart enough to get this right, I mean if I divide
> 5/2 the answer is 2.5 not 2!! By this time you are ready to flame me and
> tell me that this is proper behavior and that it has to do with the
> automatic casting feature. All I have to say about that is that just because
> it is proper behavior does not mean that is not stupid behavior.

> 1. - Is there any way to tell C to wise up and get it right without having
> to do something like Result = (float)Numerator/(float)Denominator?

that's how you are supposed to do it.

Quote:
> 2. - Is there any way to tell C not to auto cast but to crash so that is
> easy to find where the error is hiding?

There's no such thing as an "auto cast".

Quote:

All arithmetic and logical operators return the same type as their
operands. That is the way that (most) computers work, and that is the
way that C works. There's nothing illogical about it, if the C compiler
were to have to guess what type you wanted, how could you know that it
would be right?

int a = rand();
int b = rand();

/*What type should the following expression be?*/

a / b;

/*  Should the compiler insert a bunch of extra
code to see if a is an even multiple of b,
and then evaluate to an int if so, and a
float or double if not? That would be absurd.
*/

Fri, 12 Dec 2003 11:33:12 GMT
(int/int) != int

Quote:

>The following code simply does N O T make sense, check it out.

>int  Numerator = 5;
> int  Denominator = 2;
> float  Result = 0;

> Result = Numerator/Denominator;
> printf("Result = %f\n", Result);      //Results 2 and not 2.5!!

>You would think that C is smart enough to get this right, I mean if I divide
>5/2 the answer is 2.5 not 2!! By this time you are ready to flame me and
>tell me that this is proper behavior and that it has to do with the
>automatic casting feature. All I have to say about that is that just because
>it is proper behavior does not mean that is not stupid behavior.

>1. - Is there any way to tell C to wise up and get it right without having
>to do something like Result = (float)Numerator/(float)Denominator?
>2. - Is there any way to tell C not to auto cast but to crash so that is
>easy to find where the error is hiding?

c follows thge fortran rules rather than the algol rules

Result = Numerator/Denominator;

would be

Result := Numerator div Denominator

in a more rational programming language

Fri, 12 Dec 2003 12:03:03 GMT
(int/int) != int

Quote:
> > (or better yet, using appropriate types in the first place)

> The only values that were intended to go in the int variables were int
> values, the result was not intende to be int, why would it be wrong?

You could intend that the result of an int / int be a float.
You could intend that the result of int / int be an int.
You could intend that the result of int / int be a potato.

Intent is meaningless to a computer or a compiler. Feel free to attempt to
write software capable of determining human intent. If you could do so, you
would become quite wealthy, I imagine.

But if you 'intended' to ask the question:

"In an assignment, why doesn't C use the type of the lvalue to determine the
type used to promote the operands of the expression to be assigned?"

Well,

float foo;
foo = 1 + 2 + 3 + 4 + 5 + 6 + 7;

You certainly aren't going to want to promote all those. So I guess you only
want to promote operands of an expression when division is involved?

foo = 8 / 2;

Darn, we just wasted time promoting those for nothing.
Maybe C should only promote operands of a division when the result isn't
going to fit nicely into an integer? Sure, if there was a
universally-available instruction that would give you that information

As the programmer you know far more about the purpose for which you will use
your variables than any compiler can ever hope to.
If your variables make the best sense as ints, but you need to divide them,
you'll just have to cast.
If you are casting all over the place, make your variables float to begin
with, or else rethink your problem.

-Daniel

Fri, 12 Dec 2003 12:08:58 GMT
(int/int) != int

And before anyone says anything, yes, I know those expressions would be
evaulated at compile time.  :-)

-Daniel

Fri, 12 Dec 2003 12:15:21 GMT
(int/int) != int

Quote:
> The following code simply does N O T make sense, check it out.

> int  Numerator = 5;
>  int  Denominator = 2;
>  float  Result = 0;

>  Result = Numerator/Denominator;
>  printf("Result = %f\n", Result);      file://Results 2 and not 2.5!!

> You would think that C is smart enough to get this right, I mean if I
divide
> 5/2 the answer is 2.5 not 2!! By this time you are ready to flame me and
> tell me that this is proper behavior and that it has to do with the
> automatic casting feature. All I have to say about that is that just
because
> it is proper behavior does not mean that is not stupid behavior.

> 1. - Is there any way to tell C to wise up and get it right without having
> to do something like Result = (float)Numerator/(float)Denominator?

Yes.  You could write an extension to a compiler that checked the types of
all subexpressions and automaticly converted them.  Such a compiler would
not be conforming.

Quote:
> 2. - Is there any way to tell C not to auto cast but to crash so that is
> easy to find where the error is hiding?

Yes.  See above and substitute "automaticly convert" with "automaticly
crash".

Quote:

Yes.  Delaying the conversion until the expression is complete is more
efficient.  You can always use (float)x/(float)y as you described if that's
what you want, so nothing is really lost here.  Even if the two approaches
were equally efficient, you would have to pick one or the other.  This is
the one they picked.  Deal with it and move on.

Quote:

> Thank you.

--Steve

Fri, 12 Dec 2003 12:29:35 GMT
(int/int) != int

| > You call it stupid.  I call it logical.
|
| 5/2 = 2? Is this logical? Not to me, not at all. Just because you accept
| what the standard says it still does not make it a logical result. The
| standard could very well have stated that 5/2 = 2.5.
|

0000-0101 / 0000-0010 = 0000-0010,
(float)0000-0010 = 2,

yes it _IS_ logical.

it's not our fault that you can understand
the basics of how a computer and a compiler
operate.

Fri, 12 Dec 2003 13:01:30 GMT
(int/int) != int

Quote:

> The following code simply does N O T make sense, check it out.

> int  Numerator = 5;
>  int  Denominator = 2;
>  float  Result = 0;

>  Result = Numerator/Denominator;
>  printf("Result = %f\n", Result);      //Results 2 and not 2.5!!

Any time you have an expression that with mixed-type operands like
that, the compiler has to insert implicit conversions to make it work
(or, in some languages, reject it altogether).  The compiler could
insert these conversions either before the division (converting each
operand to float) or before the assignment (converting the result to
float).  C's choice is not arbitrary; it follows straightforwardly
from its rules, particularly from the rule that the type of an
expression is determined by the expression itself, not by the context
in which it appears.  (The fact that 0 is treated as a pointer in a
pointer context is an exception to this.)

A change to the language to make this case work the way you want it to
would either create a special-case wart in the language (the type of
an integer division is determined by its context) or require
far-reaching and incompatible changes in expression evaluation.

If you're accustomed to a language like Pascal, which has separate
"div" (integer) and "/" (floating-point) operators, it's admittedly a
bit surprising.  But look on the bright side: now that you've made
this error once, you're not likely to make it again.

--

San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Cxiuj via bazo apartenas ni.

Fri, 12 Dec 2003 14:10:53 GMT
(int/int) != int

Quote:

> > You call it stupid.  I call it logical.

> 5/2 = 2? Is this logical? Not to me, not at all. Just because you accept
> what the standard says it still does not make it a logical result. The
> standard could very well have stated that 5/2 = 2.5.

Why?  2.5 is not an integer.

1/3?  With your logic you will get 1.33, but that's not the answer
either.  are you stupid?

Tom

Fri, 12 Dec 2003 18:25:31 GMT
(int/int) != int

Quote:

> > (or better yet, using appropriate types in the first place)

> The only values that were intended to go in the int variables were int
> values, the result was not intende to be int, why would it be wrong?

Dude... learn some comp.sci

int a = 5;
int b = 2;
int q, r;

q = a/b;
r = a%b;

printf("%d\n", q*b+r);

Magic!

Tom

Fri, 12 Dec 2003 18:26:45 GMT

 Page 1 of 2 [ 25 post ] Go to page: [1] [2]

Relevant Pages