Author |
Message |
Rene #1 / 25
|
 (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? 3. - Is there any logical explanation about this behavior? Thank you.
|
Fri, 12 Dec 2003 10:29:08 GMT |
|
 |
Tom St Deni #2 / 25
|
 (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 |
|
 |
Ben Pfaf #3 / 25
|
 (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: > 3. - Is there any logical explanation about this behavior?
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 |
|
 |
Daniel Fo #4 / 25
|
 (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 |
|
 |
Rene #5 / 25
|
 (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 |
|
 |
Rene #6 / 25
|
 (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 |
|
 |
Clark S. Cox I #7 / 25
|
 (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: > 3. - Is there any logical explanation about this behavior?
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 |
|
 |
morgan mair fhe #8 / 25
|
 (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? >3. - Is there any logical explanation about this behavior?
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 |
|
 |
Daniel Fo #9 / 25
|
 (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 without overhead. 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 |
|
 |
Daniel Fo #10 / 25
|
 (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 |
|
 |
vrml3d.c #11 / 25
|
 (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: > 3. - Is there any logical explanation about this behavior?
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: Your welcome, --Steve
|
Fri, 12 Dec 2003 12:29:35 GMT |
|
 |
Aaron Robinso #12 / 25
|
 (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 |
|
 |
Keith Thompso #13 / 25
|
 (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 |
|
 |
Tom St Deni #14 / 25
|
 (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. What about 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 |
|
 |
Tom St Deni #15 / 25
|
 (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 |
|
|