How big is unsigned long

Built-in types (C++)

Built-in types (also called fundamental types) are specified by the C++ language standard and are built into the compiler. Built-in types aren’t defined in any header file. Built-in types are divided into three main categories: integral, floating-point, and void. Integral types represent whole numbers. Floating-point types can specify values that may have fractional parts. Most built-in types are treated as distinct types by the compiler. However, some types are synonyms, or treated as equivalent types by the compiler.

Void type

The void type describes an empty set of values. No variable of type void can be specified. The void type is used primarily to declare functions that return no values or to declare generic pointers to untyped or arbitrarily typed data. Any expression can be explicitly converted or cast to type void . However, such expressions are restricted to the following uses:

  • An expression statement. (For more information, see Expressions.)
  • The left operand of the comma operator. (For more information, see Comma Operator.)
  • The second or third operand of the conditional operator ( ? : ). (For more information, see Expressions with the Conditional Operator.)

std::nullptr_t

The keyword nullptr is a null-pointer constant of type std::nullptr_t , which is convertible to any raw pointer type. For more information, see nullptr .

Boolean type

The bool type can have values true and false . The size of the bool type is implementation-specific. See Sizes of built-in types for Microsoft-specific implementation details.

Character types

The char type is a character representation type that efficiently encodes members of the basic execution character set. The C++ compiler treats variables of type char , signed char , and unsigned char as having different types.

Microsoft-specific: Variables of type char are promoted to int as if from type signed char by default, unless the /J compilation option is used. In this case, they’re treated as type unsigned char and are promoted to int without sign extension.

A variable of type wchar_t is a wide-character or multibyte character type. Use the L prefix before a character or string literal to specify the wide-character type.

Microsoft-specific: By default, wchar_t is a native type, but you can use /Zc:wchar_t- to make wchar_t a typedef for unsigned short . The __wchar_t type is a Microsoft-specific synonym for the native wchar_t type.

The char8_t type is used for UTF-8 character representation. It has the same representation as unsigned char , but is treated as a distinct type by the compiler. The char8_t type is new in C++20. Microsoft-specific: use of char8_t requires the /std:c++20 compiler option or later (such as /std:c++latest ).

The char16_t type is used for UTF-16 character representation. It must be large enough to represent any UTF-16 code unit. It’s treated as a distinct type by the compiler.

The char32_t type is used for UTF-32 character representation. It must be large enough to represent any UTF-32 code unit. It’s treated as a distinct type by the compiler.

Floating-point types

Floating-point types use an IEEE-754 representation to provide an approximation of fractional values over a wide range of magnitudes. The following table lists the floating-point types in C++ and the comparative restrictions on floating-point type sizes. These restrictions are mandated by the C++ standard and are independent of the Microsoft implementation. The absolute size of built-in floating-point types isn’t specified in the standard.

TypeContents
float Type float is the smallest floating point type in C++.
double Type double is a floating point type that is larger than or equal to type float , but shorter than or equal to the size of type long double .
long double Type long double is a floating point type that is larger than or equal to type double .

Microsoft-specific: The representation of long double and double is identical. However, long double and double are treated as distinct types by the compiler. The Microsoft C++ compiler uses the 4- and 8-byte IEEE-754 floating-point representations. For more information, see IEEE floating-point representation.

Integer types

The int type is the default basic integer type. It can represent all of the whole numbers over an implementation-specific range.

A signed integer representation is one that can hold both positive and negative values. It’s used by default, or when the signed modifier keyword is present. The unsigned modifier keyword specifies an unsigned representation that can only hold non-negative values.

A size modifier specifies the width in bits of the integer representation used. The language supports short , long , and long long modifiers. A short type must be at least 16 bits wide. A long type must be at least 32 bits wide. A long long type must be at least 64 bits wide. The standard specifies a size relationship between the integral types:

An implementation must maintain both the minimum size requirements and the size relationship for each type. However, the actual sizes can and do vary between implementations. See Sizes of built-in types for Microsoft-specific implementation details.

The int keyword may be omitted when signed , unsigned , or size modifiers are specified. The modifiers and int type, if present, may appear in any order. For example, short unsigned and unsigned int short refer to the same type.

Integer type synonyms

The following groups of types are considered synonyms by the compiler:

Microsoft-specific integer types include the specific-width __int8 , __int16 , __int32 , and __int64 types. These types may use the signed and unsigned modifiers. The __int8 data type is synonymous with type char , __int16 is synonymous with type short , __int32 is synonymous with type int , and __int64 is synonymous with type long long .

Sizes of built-in types

Most built-in types have implementation-defined sizes. The following table lists the amount of storage required for built-in types in Microsoft C++. In particular, long is 4 bytes even on 64-bit operating systems.

TypeSize
bool , char , char8_t , unsigned char , signed char , __int8 1 byte
char16_t , __int16 , short , unsigned short , wchar_t , __wchar_t 2 bytes
char32_t , float , __int32 , int , unsigned int , long , unsigned long 4 bytes
double , __int64 , long double , long long , unsigned long long 8 bytes

See Data type ranges for a summary of the range of values of each type.

For more information about type conversion, see Standard conversions.

What’s the difference between unsigned long/long/int in c/c++?

First of all, the size of int/long is unspecified. So on your compiler, an int and a long might be the same, but this isn’t universal across compilers.

As for the difference between unsigned long and long :

Assuming 4 bytes, a long has the range of -2,147,483,648 to 2,147,483,647 . An unsigned long has the range of 0 to 4,294,967,295 .

One other difference is with overflow. For a signed type, an overflow has unspecified behavior. But for an unsigned type, overflow is guaranteed to “wrap around.”

66.4k 56 56 gold badges 180 180 silver badges 230 230 bronze badges

Wrap around is handled as overflow arithmetic. When you hit (in rlbond’s example) 4294967296 in an unsigned long, adding 1 will “wrap around” and it will become the minimum value: 0. Adding 2 will wrap around and make it 1, etc.

Seems this kinda stuff can also be done for a signed type,right?

It can be, but as rlbond said, the behavior is undefined when you overflow a signed type. Unsigned types are guaranteed to wrap properly; signed types have no such guarantee and behavior could change from one platform to the next.

4,294,967,296 should be 4,294,967,295 both in the answer and in the comment by @Dan.
I suppose I should have said “assuming four 8-bit bytes” instead.

The C language specification allows the implementation of int and long types to vary from one platform to another within a few constraints. This variability is a headache for cross-platform code, but it is also an asset because it enables the informed programmer to balance their design goals between native processor speed and full numeric range on hardware architectures that don’t offer both.

In general, “int” is supposed to map a machine register size of the target CPU architecture’s machine, so that loading, storing, and operating on the int type data should translate directly into operations that use the target processor’s native registers.

Int can be less than the machine register size in the interest of saving memory space (big ints take up twice as much RAM as little ints). It’s common to see int as a 32 bit entity even on 64 bit architectures where compatibility with older systems and memory efficiency are high priorities.

“long” can be the same size or larger than “int” depending on the target architecture’s register sizes. Operations on “long” may be implemented in software if the target architecture doesn’t support values that large in its native machine registers.

CPU chips designed for power efficiency or embedded devices are where you will find distinctions between int and long these days. Compilers for general purpose CPUs like in your desktop or laptop PC generally treat int and long as the same size because the CPU efficiently uses 32 bit registers. On smaller devices such as cell phones the CPU may be built to handle 16 bit data more naturally and have to work hard to handle 32 bit or larger data.

Fewer bits per register means fewer circuits required on the chip, fewer data lines to move data in and out of the chip, lower power consumption and smaller chip die size, all of which make for a lower cost (in $ and in watts) device.

In such an architecture, you will most likely find int to be 16 bits in size and long to be 32 bits in size. There may also be a performance penalty associated with using longs, caused by either wait states to load the 32 bits in multiple reads across a 16 bit data bus, or caused by implementing long operations (addition, subtraction, etc) in software if the native hardware doesn’t support such operations in hardware.

As a general rule, the only thing you can assume about ints and longs is that the range of int should always be less than or equal to long on any architecture. You should also assume that someday your code will be recompiled for a different architecture where whatever relationship you currently see between int and long no longer exists.

This is why you should be careful to keep ints separate from longs even in everyday mundane coding. They may be completely assignment compatible today because their implementation details for your current hardware platform coincide, but that coincidence is not guaranteed across all platforms.

Related Post

Як додати лимон у горілкуЯк додати лимон у горілку

Заливаємо лимон і м'яту горілкою. За відсутності горілки ви можете використовувати розведений спирт або самогон. Закриваємо банку кришкою, як слід збовтуємо, щоб мед розчинився в горілці. Прибираємо банку в темне

Конверсія корму у свинарствіКонверсія корму у свинарстві

Зміст:1 Корми свинарство – першорядне завдання1.1 Загальна характеристика кормів у свинарстві1.2 Рослинна їжа1.3 Концентрати в свинарстві1.4 Корми для поросят2 Конверсія корму: свинарство3 Автоматизована станція контролю відгодівельної продуктивності свиней – підвищує

Що буде після набряку мозкуЩо буде після набряку мозку

Набряк мозку (лат. oedema cerebri) — патологічний процес, що проявляється надлишковим накопиченням рідини в клітинах головного або спинного мозку (в першу чергу глії) і міжклітинному просторі, збільшенням об'єму мозку та