# Difference between data type int and long on Arduino

I was learning to program for a void obstacle robot but when I looked at the code I saw two data types long and int.

Int are datatypes that holds -2,147,483,648 to 2,147,483,647. Long are also datatypes that holds -2,147,483,648 to 2,147,483,647.

Int and long are like same but I came up with the code where two types of datatype is used as seen below:

``````int trigPin = 2;
int echoPin = 4;
long duration, cm, inches;
``````

But how can you know when to use which datatype? I searched a lot in the web but I didn't understand so can someone explain this to me please.

• "Int are datatypes that holds -2,147,483,648 to 2,147,483,647" Where did you hear that? Commented Feb 14, 2016 at 21:54

On the Arduino (AVR models) an `int` is 16 bits, not 32 bits. Thus it goes from -32768 to +32767.

That is different from `long` which is 32 bits.

• What are the widths of `int` and `long` on the 32-bit ARM Arduinos such as Due? Commented Feb 15, 2016 at 2:05
• I think on the Due that an `int` is 32 bits, the same a `long`. See here for example. Commented Feb 15, 2016 at 2:27

According to the C language specification, `int` must be at least 16 bits or longer and `long` must be at least 32 bits or longer.

It is OK for a compiler to implement `int` as 32 bits or even 64 bits. It is OK for a compiler to implement `long` as 64 bits or longer. But it is not allowed for a compiler to implement `long` as 16 bits.

So when to use which type?

If the values you will be working with can be represented within 16 bits then it's OK to use `int`. If you need more than 16 bits use `long`. If you need more than 32 bits use `long long`.

Do not be caught up with compiler and/or CPU specifics. As mentioned by others, even within the same product range, Arduinos, there are 16 and 32 bit CPUs available. Instead, only trust what the standard guarantees.

The full specification of types in C are:

• `char` must be at least 8 bits
• `int` must be at least 16 bits
• `long` must be at least 32 bits
• `long long` must be at least 64 bits

Note: It is perfectly legal for compilers to implement char, int, long and long long as 64 bits. This is in fact not uncommon among DSPs.

• Also: Read your compiler documentation Commented Feb 15, 2016 at 2:21
• And: `sizeof(char) <= sizeof(int) <= sizeof(long) <= sizeof(long long)` according to standard. So, if `int` is 64 bits, then `long` must also be at least 64 bits. Commented Feb 15, 2016 at 9:21

`int` in AVR GCC is 16 bits, not 32.

It's the same reasoning as in C: the size of the `int` type is expected to be the natural word size that your system handles most efficiently. It must also be at least 16 bits wide, no smaller than a `short`, and no larger than a `long`.

So an `int` may be 16-, 32-, or 64-bits, based on the whatever your system handles best, and so is most likely to be 16 bits wide on an 8- or 16-bit CPU, 32 on a 32-bit CPU etc.

I use `int` when I want the best performance, whilst taking care to guard when I need more range than offered by 16 bits. These days, you tend to know when you are writing application code for 16-bit systems, although that's not so true for "library" code where portability may be of greater concern.

In your example, assuming the author had chosen their types carefully, the `int` variables probably require a small range and could afford to be word-size, leading to potentially shorter or faster code (or both). The `long` ones presumably required more than 16-bit range (they are guaranteed to be at least 32 bits wide). On the processor you'd selected as a compilation target, it looks like `int` and `long` were both implemented as 32-bit; this would be different (or should be) if you selected a 16-bit target CPU.

I like to use types from `stdint.h`.

While they do have minor drawbacks, the benefit they provide is you know exactly the size your are handling, even when compiling on other architectures.

``````#include <stdint.h>

uint8_t  my_byte = 0xf0;
int16_t  trig_pin = 2;
int16_t  echo_pin = 4;
uint32_t duration, cm , blah;
uint64_t big_int;

// etc.
``````

But obviously you don't want to be moving around a bunch of int32_t when your data only needs int16_t.

• So not using machine word size does not impact performance on AVR?
– René
Commented Feb 15, 2016 at 7:54
• @René - Generally not using word size can impact performance on most CPUs. But traditionally AVR CPUs have 8bit registers & accumulators with some 16 bit instructions for pointer operations. So when I program, I get the code running first, then optimise for speed if it's too slow. Commented Feb 16, 2016 at 3:10
• @René - But if you really want to be pedantic about it, you could use `word` as your data type. This is 16 bits on Arduino Uno, and 32 bits on Arduino Due & Zero. But this comes back to the problem of really only knowing the minimum size of your data type. Say you use `word` on some Due code, but then want to back-port to Uno?! Using uint32_t instead would solve this problem before it starts, but yes it will be word-size sub-optimal on Uno. What about future Arduino boards ... what word size will they have? 32? 64? 128!? Commented Feb 16, 2016 at 3:22
• OK. So I would use the machine word size (int? WORD seems to be an obselete windows type definition) if the lower limit is sufficient, I do not care about memory size and need the speed, *_t if I care about size?
– René
Commented Feb 16, 2016 at 17:03
• scrap that ... gnu.org/software/libc/manual/html_node/Integers.html says `*fast*_t` seems to be the way to go ...
– René
Commented Feb 16, 2016 at 17:04

if you are using Esp32 boards in Arduino IDE: