Go Down

Topic: Variable type resulting from multiplying dissimilar types (Read 218 times) previous topic - next topic

tduffett

When a const int variable is multiplied by an unsigned long variable what is the resultant data type?

i.e. the following is the last function in a sketch (attached) that flashes a 10 segment LED bar graph like a binary counter display. LEDs 1-7 worked fine. LEDs 8-10 only worked if the flash interval was reduced ultimately down to 50ms to get LED10 to work, until I changed the variable type for the flash interval to unsigned long also. It looked like the result of the "(currentMillis%(512*I)) was overflowing when millis() went above 64000 so LED 8, 9 and 10 never went high. Once I change the flash interval type it worked fine with flash interval set to 500.

I did not see anywhere I looked where the data type of two dissimilar variables multiplied together was defined. Can anyone help me to understand?


const int I=500;                                                                     // flash interval
unsigned long LED10Interval = 512*I;                                     //interval to blink LED10 LED (milliseconds)

void manageLED10() {                                                              //LED10 function
    currentMillis = millis();                                                          //capture the current time
    if(currentMillis - previousMillisLED10 >= LED10Interval) {       //check if time to change LED10 LED yet
    LED10State = (LED10State == HIGH) ? LOW : HIGH;             //if state is high change to low
    digitalWrite(LED10Pin, LED10State);                                      //change output of pin to match state
    previousMillisLED10 = (currentMillis-(currentMillis%(512*I))); //store the time of this change
    }
}

larryd

You can easily prove things by using Serial.println() on your variables.

example:
Serial.println(myVariable);  // print value of 'myVariable' to see what an operation did to it

unsigned int var1 = 16000;
unsigned long var2 = 100000;

var1 = var1 * var2;
Serial.println(var1);
var2 = var2 * var1;
Serial.println(var2);

Serial.println(var1 * var2);
.
No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

MorganS

There is a defined hierarchy so that an expression always upgrades its result type to the 'highest' of the input types.

However this does not guarantee that the result actually fits. If you have a int containing INT_MAX then even adding 1 to it will result in an overflow.
"The problem is in the code you didn't post."

westfw

Quote
When a const int variable is multiplied by an unsigned long variable what is the resultant data type?
unsigned long.   However, I do not see any such case in your sample of code.  Numeric constants are considered to be of type "int" unless they don't fit, so your expressions involving
Code: [Select]
512*I;
are both "int * unsigned int", which will result in an unsigned int.  (and 500 * 512 doesn't fit in an unsigned int, so you won't get the value you expect.   The type of the destination of an assignment does not have any effect on the types used on the right hand side of the expression.

Go Up