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? – Lightness Races in Orbit Feb 14 '16 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? – hexafraction Feb 15 '16 at 2:05
  • I think on the Due that an int is 32 bits, the same a long. See here for example. – Nick Gammon Feb 15 '16 at 2:27

int in AVR GCC is 16 bits, not 32.


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 – slebetman Feb 15 '16 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. – Residuum Feb 15 '16 at 9:21

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é Feb 15 '16 at 7:54
  • 1
    @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. – Kingsley Feb 16 '16 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!? – Kingsley Feb 16 '16 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é Feb 16 '16 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é Feb 16 '16 at 17:04

Your Answer

