I am trying to put the result of a calculation that uses an int and an uint8_t and for testing purposes lets include a float aswell.
Do i need to convert every parameter of the calculation to and unsigned long using the (unsigned long) datatype prefix inside the calculation to have a proper and usable as unsigned long result?
for example:
int a = 3054;
uint8_t b = 6;
float c = 1.15;
unsigned long Result = (a/b)*c;
I'm pretty sure this is gonna do al sorts of wacky things so my question is how to properly do this?
What works and what is the best approach to this?
unsigned long Result = (unsigned long) ((a/b)*c);
or must i convert every single non unsigned long into an UL seperatly?: unsigned long Result = ( (unsigned long) a / (unsigned long)b) * (unsigned long) c);
offcourse this way the float vallue will completely change the result here, a better way i believe should be to convert the result of the calculation to have the best accuracy?
No. The compiler promotes every variable in the calculation so that the calculation is done in the "highest" form, but the rules are a bit complicated. Look up something like "C/C++ type promotion".
If one variable is declared unsigned long, shorter integers will also be treated as unsigned long. A float supersedes unsigned long.
unsigned long Result;
unsigned long Result = (a/b)*c;
and
unsigned long Result;
Result = ( unsigned long) a /b)*c;
and
unsigned long Result;
Result = (unsigned long) ((a /b)*c);
are all perfectly viable options?
I am going to use the Result in a comparison check using micros();
I've read somewhere that usually you have to put UL at the end of the value when using unsigned long, but i assume that is done automaticly after the calculation?
hmm, so in my calculation i would only need to place the UL tag right after the last number incase i use digits in the equation? doing this once will ultimately convert the final result into an UL?
would that be the same as having unsigned long Result = (unsigned long) ((a /b)*c);
and unsigned long Result = (a /6UL)*c;
and what happens when i put the UL tag in a float 1.15UL would that convert it to 1 or to 115?
No, it is not going to do ANY "wacky things". It will follow the very precise and detailed rules specified for c++ expression evaluation and type conversion. You would be wise to study and LEARN those rules rather than trying things blindly until you get the result you want.
UL stands for unsigned long int, and it is used for a variable that wil hold number with no frcational part; but. 1.15 is a number that has a fractional part; so, 1.15UL is illegal?
You can easily mess up. Order is important, as is your ().
Consider:
void setup() {
Serial.begin(115200);
int a = 3053; //changed between runs
uint8_t b = 6;
float c = 1.15;
unsigned long Result;
float Result2;
Serial.println("-----------------");
Serial.print("a,b,c ");
Serial.print(a);
Serial.print(" ");
Serial.print(b);
Serial.print(" ");
Serial.println(c);
//with an int output
Result = (a / b) * c;
Serial.println(Result);
Result = a / b * c;
//...different order
Serial.println(Result);
Result = c * a / b;
Serial.println(Result);
Result = c * (a / b);
//with a float output
Serial.println(Result);
Result2 = (a / b) * c;
Serial.println(Result2);
Result2 = a / b * c;
//...different order
Serial.println(Result2);
Result2 = c * a / b;
Serial.println(Result2);
Result2 = c * (a / b);
Serial.println(Result2);
}
void loop() {}