View previous topic :: View next topic |
Author |
Message |
carlosma
Joined: 24 Mar 2004 Posts: 53 Location: Portugal
|
division with 2 int |
Posted: Wed Mar 23, 2005 10:21 am |
|
|
please
I have this problem:
Code: |
int16 var_a= 779, var_b=120;
float total;
total = var_a / var_b;
|
total now have the value 6 but I need the real value 6.4916
Thanks
Carlos |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Wed Mar 23, 2005 10:36 am |
|
|
try
Code: | total = (float)var_a / var_b; |
|
|
|
r520m Guest
|
|
Posted: Mon May 09, 2005 10:01 pm |
|
|
Will Reeve wrote: | try
Code: | total = (float)var_a / var_b; |
|
Hi Will
Can you explain the differnce between
Code: | total=(float)var_a/var_b; |
and
Code: | float total;
total=var_a/var_b |
The first code prints the int and dec part of float, but, why the second code dont print the decimal part of total???
I have tryn to print a following code
Code: | int adc_result;
float value;
value=(adc_result*5)/255;
printf("Values is %2.2f",valor); |
this prints "3.00", which is wrong when exits a decimal part...
Thank you very much... |
|
|
icefield
Joined: 09 May 2005 Posts: 20 Location: Canada
|
|
Posted: Mon May 09, 2005 11:58 pm |
|
|
All the expressions causing problems (appearing to truncate) are composed entirely of integers, so the compiled generates code to do integer math. In integer math, 10/4 = 2, not 2.5. Then you assign the resulting integer value to a float variable, but it's a floating point representation of an integer result.
To force the compiler to generate floating point math for the expression, you have to convert (or typecast) one or more of the arguments to type FLOAT. This is what "(float)" does - it tells the compiler to convert the expression to its right into a float value.
This is standard C, but can trap you. The other major type pitfall is when working with signed and unsigned integers and converting between 8, 16, and 32-bit versions thereof.
Cheers,
Erik |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Tue May 10, 2005 12:08 pm |
|
|
CCS has some non ANSI rules with casts, automatic casting not always
happen as expected.
Try this:
float total;
total = (float)var_a / (float)var_b;
Humberto |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Tue May 10, 2005 3:52 pm |
|
|
Humberto wrote: | CCS has some non ANSI rules with casts, automatic casting not always
happen as expected.
Try this:
float total;
total = (float)var_a / (float)var_b;
Humberto |
The rule in the manual is "when a binary operator has operands of differing types, then the lower order operand is converted to the higher". Floats sit at the top of the order
By this rule, one typecast as float should be enough. That said, I've been bitten by typecasting problems often enough-- so often that I haven't even convinced myself that the compiler follows this publised rule.
Scott |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Tue May 10, 2005 6:17 pm |
|
|
Hi Scott,
sseidman wrote:
Quote: |
The rule in the manual is "when a binary operator has operands of differing types, then the lower order operand is converted to the higher". Floats sit at the top of the order
|
The point is not what the manual rule say, the point is what the compiler does.
In the following expresion
total = (float)var_a / (float)var_b;
I´m agree with you that may be a non-elegant notation but for sure it´s very aseptic
and fool proof. I've been bitten most times by typecasting problems too.
Search "float" in this forum just to see how many times this discusion had been done.
Keep well,
Humberto |
|
|
bfemmel
Joined: 18 Jul 2004 Posts: 40 Location: San Carlos, CA.
|
Bitten by Compiler |
Posted: Wed May 11, 2005 12:23 pm |
|
|
I'm with Humberto. I had a simple equation that didn't seem to want to compile correctly until I added what I thought were superfluous type casting statements like this:
Code: | sumValue += (signed int32) ( (signed int16) MAKE16(ADC_MSB,ADC_LSB) ); // Add the recent value to the sum
|
I am not sure why I needed to cast the operand to 32 bits before I added it to a 32 bit number but I did. I guess the compiler did not do the sign extension it should have done.
So when in doubt "SPELL IT OUT"
Bruce |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
Re: Bitten by Compiler |
Posted: Wed May 11, 2005 12:47 pm |
|
|
bfemmel wrote: | I'm with Humberto. I had a simple equation that didn't seem to want to compile correctly until I added what I thought were superfluous type casting statements like this:
Code: | sumValue += (signed int32) ( (signed int16) MAKE16(ADC_MSB,ADC_LSB) ); // Add the recent value to the sum
|
I am not sure why I needed to cast the operand to 32 bits before I added it to a 32 bit number but I did. I guess the compiler did not do the sign extension it should have done.
So when in doubt "SPELL IT OUT"
Bruce |
I'm certainly getting there. I think my costliest bugs, in terms of debugging time, has come from typecasting errors. That said, when a whole room of people agree that a typecast is superfluous, and it follows the published rules, and it costs unsuspecting developers a ton of time, I would think that CCS would want to address the bug.
Scott |
|
|
icefield
Joined: 09 May 2005 Posts: 20 Location: Canada
|
|
Posted: Wed May 11, 2005 1:03 pm |
|
|
The default integer type is unsigned, so if you are doing integer math and want signed results, you have to say so. There's another thread going right now that discusses this: http://www.ccsinfo.com/forum/viewtopic.php?t=22820
I would say that the reason for this (non-ANSI) implementation is that with microprocessors an awful lot of stuff is done with bits and nibbles, etc. and the behaviour of unsigned is straightforward (in the sense that bits don't get set as side-effects of math operations as they so with signed variables).
Cheers,
Erik |
|
|
Ttelmah Guest
|
|
Posted: Wed May 11, 2005 2:13 pm |
|
|
There is a significant 'plus' to the CCS way of behaving, for an embedded controller. Their default is to assume the smallest (and quickest to calculate) type, unless the code explicitly defines otherwise (either by the types involved, or casting). This results in faster and smaller code. As such it is different from how explicit casting normally behaves, but it leaves the developer with the choice of how he/she want's the code to behave.
Best Wishes |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Wed May 11, 2005 2:57 pm |
|
|
Ttelmah wrote: | There is a significant 'plus' to the CCS way of behaving, for an embedded controller. Their default is to assume the smallest (and quickest to calculate) type, unless the code explicitly defines otherwise (either by the types involved, or casting). This results in faster and smaller code. As such it is different from how explicit casting normally behaves, but it leaves the developer with the choice of how he/she want's the code to behave.
Best Wishes |
I have no problem with this behavior, but let's take a look at the example at hand, the float division of two integers. We should certainly all categorically know, like the backs of our hands, whether we need to use
Code: |
total = (float)var_a / (float)var_b;
or
total = (float)var_a / var_b;
|
The answer should be deterministic, there should be no wondering about whether you need to add the extra typecast or not for an expression as simple as this.
I suppose one could argue that its good to get into the habit of expressing these things explicitly, as it can sometimes get confusing. That said, anybody who sits down with the compiler documentation and any given expression should be able to correctly know what the expression will evaluate to without actually evaluating it. If this isn't the case (and I don't think it is), then the documentation is insufficient.
Scott |
|
|
|