I'm having some problems and getting confused about the proper way of doing some operations with uint16_t and double for C embedded software (Using GCC).
Ex1:
uint16_t PD_input =723;// Input will always be greater than output
uint16_t PD_output =246;
uint16_t FQ_u16 = PD_input/PD_output;
This will result in: FQ_u16=2, no?
Ex2:
uint16_t PD_input =723;
uint16_t PD_output =246;
double FQ_dbl = PD_input/PD_output;
In this case FQ_dbl =2.9390, but I get 0.... or should I do:
double FQ_dbl = (double)(PD_input/PD_output);
In this case I don't know if doinng the casting will cause some problems. I get 0 anyway.
If I do the casting on the other side the next example will be correct, or how should I do it? Ex3:
double FQ_dbl = PD_input/PD_output;
uint16_t var= (uint16_t)FQ_dbl; //Is this correct?
What is the proper way of dividing two uint16_t? What is the proper way of casting/convert a double to an uint16_t?
Ex4:
uint16_t var=7342;
double target = var/1000;
target=7.342?-->I get 0
EDIT: I try this example using UNITY (It uses GCC)
uint16_t Operations(void)
{
uint16_t PD_input=723;
uint16_t PD_output=246;
uint16_t FQ_u16_raw=PD_input/PD_output;
uint16_t FQ_u16 = (PD_input + (PD_output >> 1)) / PD_output;
printf("FQ_u16: %d, FQ_u16_raw: %d",FQ_u16,FQ_u16_raw);
double FQ_dbl=(PD_input/PD_output);
printf("\nFQ_dbl: %d, FQ_dbl:%f",FQ_dbl,FQ_dbl);
FQ_dbl=(double)(PD_input/PD_output);
printf("\nFQ_dbl: %d, FQ_dbl:%f",FQ_dbl,FQ_dbl);
FQ_dbl=((double)PD_input)/PD_output;
printf("\nFQ_dbl: %d, FQ_dbl:%f",FQ_dbl,FQ_dbl);
printf("\n********************");
uint16_t target=7341;
double target_dbl=target/1000;
printf("\ntarget_dbl: %d,target_dbl:%f",target_dbl,target_dbl);
return FQ_u16;
}
I get this as output:
For a divide operation to be promoted to double
at least one of teh operatnds must be double
. To that end you need to cast one or both operands, not the expression after the divide operation. So in:
double FQ_dbl = (double)(PD_input/PD_output);
PD_input/PD_output
is an integer divide which you then explicitly cast to double
(though it would implicitly cast in any case).
What you need in this case is:
double FQ_dbl = (double)PD_input / PD_output ;
Casting PD_input
to double implicitly promotes PD_output
to double
and provided a floating point divide.
You could equally be explicit throughout:
double FQ_dbl = (double)PD_input / (double)PD_output ;
but it is equivalent.
For expressions involving literal constants such as:
double target_dbl = target / 1000 ;
it is sufficient to use a double
literal as follows:
double target_dbl = target / 1000.0 ;
but again:
double target_dbl = (double)target / 1000.0 ;
is the explicit equivalent.
As an aside, you are consistently using the wrong formatter ( %d
) for outputting a double
. You need %f
. Include -Wformat
(GCC) in your compile options to catch such errors (I think -Wformat
is implicit in Wall
that you should use in any case together with -Werror
- do not ignore the warnings, they are often indicative of semantic errors as opposed to syntactic errors).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.