user82149: I have discovered a strange error in my Arduino. It's not in the code. I think it's a hardware bug in the ALU of the microcontroller, maybe in clone only.
So there is a variable called feedLimit and its value is 30, which doesn't really matter.
When I print the answer of feedLimit301000 using this command Serial.println(feedLimit*30*1000)
The answer printed on the serial monitor is 30528, which is obviously incorrect. But when I print feedLimit*30000, the answer is correct (300000). The answer should be the same in both cases but it's not. I have attached the code as well as a screenshot of the output.
Can somebody please let me know if this is a bug in Arduino or something else? I have never experienced this kind of bug at the hardware level.
Thanks.
int interval, interval2;

int feedingTime = 3; //Must feed once every 3 minutes
int feedLimit = 30;  //If fed 10 times or more within feedingTime span, the fiesh dies
int dieAfter = 30;   //Will die if its not fed in 10 minutes
int feedCounter = 0; //Counts how many time fed in feedingTime span

void setup() {
  Serial.begin(9600);
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  Serial.println(feedLimit);
  Serial.println(feedLimit*60*1000);
  Serial.println(feedLimit*60000);
}



user4143: This is not a bug. It's just that you are working with signed 16 bit integers on an 8 bit microcontroller. The maximum an int can store is 32767, and literals are 16 bit signed by default.
Your three prints are:
  Serial.println(feedLimit);

Print 30.
  Serial.println(feedLimit*60*1000);

Multiply  feedLimit by 60 = 1800. Multuply 1800 by 1000 = 1800000. Fit 1800000 into 16 bit signed = 30538. Also works the other way: preprocessor multiplies two 16 bit ints to create a new 16 bit int constant: 60 * 1000 = 60000, which is too big to fit in an int and truncates to 27232. Multiply by 30 = 30538 when truncated to 16 bits.1
  Serial.println(feedLimit*60000);

Multiply 30 by 60000. 60000 is too big to store in an int so it is implicitly promoted to a long. 30 * 60000 = 1800000. The result is a long because you have an implicit long in your calculation.
You have to take care with big numbers on small microcontrollers and keep in mind the limits of each variable type, along with what the default data type for literals is.

char: -128 to +127
unsigned char / byte: 0 to 255
int: -32,768 to +32,767
unsigned int: 0 to 65,535
long: -2,147,483,648 to 2,147,483,647
unsigned long: 0 to 4,294,967,295

You can force literals to be a specific data type by adding a suffix to them:

L: Long
UL: Unsigned long

(There are others too but less often used).
So your first (failed) calculation can be fixed by forcing one of the values to be a long:
  Serial.println(feedLimit*60*1000L);


1: It seems avr-gcc isn't clever enough to do this, instead it's always treating each operation separately, and each time it works from int-to-int using two 8-bit registers to represent each value or result.

82149: <p>I have discovered a strange error in my Arduino. It's not in the code. I think it's a hardware bug in the ALU of the microcontroller, maybe in clone only.
So there is a variable called <code>feedLimit</code> and its value is 30, which doesn't really matter.
When I print the answer of feedLimit<em>30</em>1000 using this command <code>Serial.println(feedLimit*30*1000)</code>
The answer printed on the serial monitor is 30528, which is obviously incorrect. But when I print feedLimit*30000, the answer is correct (300000). The answer should be the same in both cases but it's not. I have attached the code as well as a screenshot of the output.
Can somebody please let me know if this is a bug in Arduino or something else? I have never experienced this kind of bug at the hardware level.
Thanks.</p>
<pre><code>int interval, interval2;

int feedingTime = 3; //Must feed once every 3 minutes
int feedLimit = 30;  //If fed 10 times or more within feedingTime span, the fiesh dies
int dieAfter = 30;   //Will die if its not fed in 10 minutes
int feedCounter = 0; //Counts how many time fed in feedingTime span

void setup() {
  Serial.begin(9600);
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  Serial.println(feedLimit);
  Serial.println(feedLimit*60*1000);
  Serial.println(feedLimit*60000);
}
</code></pre>
<p><a href="https://i.stack.imgur.com/dy93B.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/dy93B.png" alt="enter image description here" /></a></p>
 4143: <p>This is not a bug. It's just that you are working with signed 16 bit integers on an 8 bit microcontroller. The maximum an <code>int</code> can store is 32767, and literals are 16 bit signed by default.</p>
<p>Your three prints are:</p>
<pre class="lang-cpp prettyprint-override"><code>  Serial.println(feedLimit);
</code></pre>
<p>Print 30.</p>
<pre class="lang-cpp prettyprint-override"><code>  Serial.println(feedLimit*60*1000);
</code></pre>
<p>Multiply  <code>feedLimit</code> by 60 = 1800. Multuply 1800 by 1000 = 1800000. Fit 1800000 into 16 bit signed = 30538. Also works the other way: preprocessor multiplies two 16 bit ints to create a new 16 bit int constant: 60 * 1000 = 60000, which is too big to fit in an int and truncates to 27232. Multiply by 30 = 30538 when truncated to 16 bits.<sup>1</sup></p>
<pre class="lang-cpp prettyprint-override"><code>  Serial.println(feedLimit*60000);
</code></pre>
<p>Multiply 30 by 60000. 60000 is too big to store in an int so it is implicitly promoted to a long. 30 * 60000 = 1800000. The result is a long because you have an implicit long in your calculation.</p>
<p>You have to take care with big numbers on small microcontrollers and keep in mind the limits of each variable type, along with what the default data type for literals is.</p>
<ul>
<li>char: -128 to +127</li>
<li>unsigned char / byte: 0 to 255</li>
<li>int: -32,768 to +32,767</li>
<li>unsigned int: 0 to 65,535</li>
<li>long: -2,147,483,648 to 2,147,483,647</li>
<li>unsigned long: 0 to 4,294,967,295</li>
</ul>
<p>You can force literals to be a specific data type by adding a suffix to them:</p>
<ul>
<li>L: Long</li>
<li>UL: Unsigned long</li>
</ul>
<p>(There are others too but less often used).</p>
<p>So your first (failed) calculation can be fixed by forcing one of the values to be a long:</p>
<pre class="lang-cpp prettyprint-override"><code>  Serial.println(feedLimit*60*1000L);
</code></pre>
<hr />
<p><sup>1: It seems avr-gcc isn't clever enough to do this, instead it's always treating each operation separately, and each time it works from int-to-int using two 8-bit registers to represent each value or result.</sup></p>
