Variable size/Set: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(37 intermediate revisions by 17 users not shown)
Line 4:
Demonstrate how to specify the minimum size of a variable or a data type.
<br><br>
 
=={{header|11l}}==
In 11l, for base types, the size of a variable is determined by the type. There is some flexibility, as it is possible to choose the type according to the required size. For instance, for signed integers, we can choose among Int8, Int16, Int32 and Int64. The size of the variable of type “Int” is 32 or 64 bits according to the platform. The same exists for unsigned integers (Byte, UInt16, UInt32, UInt64) and for floating point numbers (Float32, Float64/Float).
 
=={{header|360 Assembly}}==
The 360 architecture data specifications are:
<syntaxhighlight lang="360 assembly">
<lang 360 Assembly>
* Binary interger (H,F)
I2 DS H half word 2 bytes
Line 33 ⟶ 36:
A4 DC A(176) 4 bytes but only 3 bytes used
* (24 bits => 16 MB of storage)
</syntaxhighlight>
</lang>
 
=={{header|6502 Assembly}}==
 
Syntax will vary depending on the assembler and whether your program will run in RAM or ROM.
For programs that execute from RAM such as those that are loaded from a disk, you can use the same syntax that you would use to define constants. When defining bytes as variables or constants, you do not prefix them with a # sign. Only in actual CPU instructions do you need to use a # to prevent the assembler from treating the numeric value as a memory location.
 
Since these are variables, the value given to them (in this case, 0) is the initial value, and can be changed later at runtime. If you don't care what the initial value is, some assemblers allow you to use a "?" where the 0s are.
 
<syntaxhighlight lang="6502asm">MyByte:
byte 0 ;most assemblers will also accept DB or DFB
MyWord:
word 0 ;most assemblers will also accept DW or DFW
MyDouble:
dd 0</syntaxhighlight>
 
For programs that are executed solely from ROM, such as video game console cartridges, you won't be able to use the above method. The assembler can often use an <code>enum</code> or <code>rsset</code> directive to sequentially assign labels to a series of consecutive memory locations in the system's RAM.
 
<syntaxhighlight lang="6502asm">.rsset $00 ;starting at $0400, the following labels represent sequential memory locations of length ".rs n"
VBlankFlag .rs 1 ;$00
soft_PPUCTRL .rs 1 ;$01
soft_PPUSTATUS .rs 1 ;$02
soft_SCROLL_X .rs 1 ;$03
soft_SCROLL_Y .rs 1 ;$04
temp_16 .rs 2 ;$05,$06
tempStack .rs 1 ;$07</syntaxhighlight>
 
Assemblers that don't have an <code>enum</code> or <code>rsset</code> directive can use the <code>equ</code> directive instead. This method lets you immediately see what each memory location actually is, but it makes it harder to insert a new one without having to redo all the numbering. Certain 6502 instructions rely on two memory addresses being consecutive.
 
<syntaxhighlight lang="6502asm">VBlankFlag equ $00
soft_PPUCTRL equ $01
soft_PPUSTATUS equ $02
soft_SCROLL_X equ $03
soft_SCROLL_Y equ $04
temp_16 equ $05 ;you have to keep track of spacing yourself in this method
tempStack equ $07</syntaxhighlight>
 
While setting a variable's size is easy, getting it isn't possible without knowing it in advance. The CPU does not (and cannot) know the intended size of a variable. There's no enforcement of types whatsoever on the 6502; anything is fair game.
 
=={{header|68000 Assembly}}==
{{trans|6502 Assembly}}
Syntax will vary depending on the assembler and whether your program will run in RAM or ROM.
For programs that execute from RAM such as those that are loaded from a disk, you can use the same syntax that you would use to define constants. When defining bytes as variables or constants, you do not prefix them with a # sign. Only in actual CPU instructions do you need to use a # to prevent the assembler from treating the numeric value as a memory location.
 
Since these are variables, the value given to them (in this case, 0) is the initial value, and can be changed later at runtime. If you don't care what the initial value is, some assemblers allow you to use a "?" where the 0s are.
 
<syntaxhighlight lang="68000devpac">MyByte:
DC.B 0
EVEN ;you need this to prevent alignment problems if you define an odd number of bytes.
MyWord:
DC.W 0 ;this takes up 2 bytes even though only one 0 was written
MyLong:
DC.L 0 ;this takes up 4 bytes even though only one 0 was written</syntaxhighlight>
 
For programs that are executed solely from ROM, such as video game console cartridges, you won't be able to use the above method. The assembler can often use an <code>enum</code> or <code>rsset</code> directive to sequentially assign labels to a series of consecutive memory locations in the system's RAM. Assemblers that don't have an <code>enum</code> or <code>rsset</code> directive can use the <code>equ</code> directive instead. This method lets you immediately see what each memory location actually is, but it makes it harder to insert a new one without having to redo all the numbering. These variables are located in the heap and thus there is no need to use <code>EVEN</code> directives to align this data.
 
<syntaxhighlight lang="68000devpac">
Cursor_X equ $100000 ;byte - only comments can tell you the intended variable size.
Cursor_Y equ $100001 ;byte
tempWord equ $100002 ;word - also occupies $100003
tempLong equ $100004 ;long - also occupies $100005,6,7</syntaxhighlight>
 
 
While setting a variable's size is easy, getting it isn't possible without knowing it in advance. The CPU does not (and cannot) know the intended size of a variable. There's no enforcement of types whatsoever on the 6502; anything is fair game.
 
=={{header|8086 Assembly}}==
Syntax will vary depending on the assembler you're using, but the following should apply to most assemblers.
 
<syntaxhighlight lang="asm">
.data ;data segment
 
TestValue_00 byte 0 ;an 8-bit variable
TestValue_01 word 0 ;a 16-bit variable
TestValue_02 dword 0 ;a 32-bit variable
 
.code
 
start:
 
mov dh, byte ptr [ds:TestValue_00] ;load the value stored at the address "TestValue_00"
mov ax, word ptr [ds:TestValue_01] ;load the value stored at the address "TestValue_01"</syntaxhighlight>
 
For programs that are executed from ROM, such as those on video game cartridges, the above syntax can only be used to define constants. Defining variables will need to be done using <code>equ</code> directives, and you'll need to read the system's documentation to know where the heap is located. For example, the Bandai Wonderswan has its heap located starting at memory address <code>100h</code>.
 
There is some enforcement of variable sizes, but it's not as strict as most other languages. The two commands above would not have worked had the wrong register sizes been used. However, using the wrong labels is perfectly legal in the eyes of most assemblers.
 
<syntaxhighlight lang="asm">mov al, byte ptr [ds:TestValue_02]
;even though this was listed as a dword in the data segment, the assembler lets us do this!</syntaxhighlight>
 
In fact, data sizes don't matter to the CPU all that much, as the following definitions are all equivalent:
<syntaxhighlight lang="asm">foo byte 0,0,0,0
bar word 0,0
baz dword 0</syntaxhighlight>
 
The data types are more for the programmer's convenience, so that it's clear how the data should be interpreted.
 
Data can be organized in a table for better readability; however it has no effect on how the data is structured apart from visually. (The data will be organized in a linear fashion regardless, so it makes no difference to the CPU). The following two structures are the same:
<syntaxhighlight lang="asm">Array1 byte 00,01,02,03
 
Array2 byte 00,01
byte 02,03</syntaxhighlight>
 
If you have a variable of a pre-determined size that isn't 1, 2, or 4 bytes you can use the following to define it:
<syntaxhighlight lang="asm">BigNumber byte 256 dup (0) ;reserve 256 bytes, each equals zero</syntaxhighlight>
 
While it's easy to set a variable's size, getting it is impossible without knowing it in advance. Variables are nothing more than just a section of RAM; the CPU does not (and cannot) know how many bytes your variable is supposed to be.
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">type Response is (Yes, No); -- Definition of an enumeration type with two values
for Response'Size use 1; -- Setting the size of Response to 1 bit, rather than the default single byte size</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
Syntax will vary depending on your assembler. VASM uses <code>.byte</code> for 8-bit data, <code>.word</code> for 16-bit data, and <code>.long</code> for 32-bit data, but this is not the norm for most assemblers, as a "processor's word size" is usually the same as its "bitness." I'll use the VASM standard anyway, just because. When defining data smaller than 32-bits, there needs to be sufficient padding to align anything after it to a 4-byte boundary. (Assemblers often take care of this for you, but you can use a directive like <code>.align 4</code> or <code>.balign 4</code>to make it happen.
 
<syntaxhighlight lang="arm assembly">.byte 0xFF
.align 4
.word 0xFFFF
.align 4
.long 0xFFFFFFFF</syntaxhighlight>
 
Keep in mind that although you may have <i>intended</i> the data to be of a particular size, the CPU does not (and cannot) enforce that you use the proper length version of <code>LDR/STR</code> to access it. It's perfectly legal for the programmer to do the following:
 
<syntaxhighlight lang="arm assembly">main:
ADR r1,TestData ;load the address TestData
LDRB r0,[r1] ;loads 0x000000EF into r0 (assuming the CPU is operating as little-endian, otherwise it will load 0x000000DE)
BX LR
TestData:
.long 0xDEADBEEF</syntaxhighlight>
 
The reverse is also true; you can point a register to the label of a <code>.byte</code> data directive and load it as a long, which will give you the byte along with the padding that it would receive to keep everything aligned. Generally speaking, you don't want to do this, as it can lead to problems where a register doesn't contain what the code assumes it does. However, being able to ignore typing at will can be advantageous, such as when trying to copy large blocks of consecutive memory, where you can achieve more throughput by copying 32 bits per instruction instead of only 8 or 16.
 
=={{header|AutoHotkey}}==
Line 48 ⟶ 176:
Variable sizes are in chunks relating to the type of data that they contain. There may also be additional bytes of storage in the variable table that do not show in the dimensions. Typically, strings are allocated in single characters (bytes), so C$(12) in the following example is stored as 12 bytes + additional bytes used for the header in the variable table. In some implementations of basic (such as those that support the storage of variable length strings in arrays), additional terminator characters (such as a trailing Ascii NUL) may also be included. In traditional basic, integers are typically 2 bytes each, so A%(10) contains 10 lots of 2 bytes (20 bytes in total) + additional bytes used for header data in the variable table. Floating point values are typically 8 bytes each, so B(10) holds 10 lots of 8 bytes (80 bytes in total) + additional bytes for header in the variable table:
 
<langsyntaxhighlight lang="basic">10 DIM A%(10): REM the array size is 10 integers
20 DIM B(10): REM the array will hold 10 floating point values
30 DIM C$(12): REM a character array of 12 bytes</langsyntaxhighlight>
 
==={{header|BBCApplesoft BASIC}}===
The first time a (non-array) variable is used a minimum of 7 bytes of memory are used. Seven bytes is the minimum size for 3 of the data types: floating point (or real), integer, and string. Two bytes are used to store the two character variable name and the data type. The five remaining bytes are used to store the data. Floating point values are 40-bit Microsoft Binary Format (MBF) which are 5 bytes in size: 1 byte signed exponent, and a 4 byte mantissa / 32-bit signed signficand. Integers are 16 bit signed integers: 2 bytes in size with the zeroes in the remaining 3 bytes. Strings are 3 bytes in size: 1 byte for the length of the string, a 2 byte (16 bit pointer) to the string, and zeroes in the remaining 2 bytes.
 
Defined functions use 14 bytes. 6 bytes are used to store a pointer to the definition: the 2 character function name and the function data type, a 2 byte pointer to the function within the program, and a 2 byte pointer to the local variable storage. An additional 3 bytes are used to store a copy of the first character of the function, and a two character local variable name. 5 bytes are used to store the local floating point variable.
 
Arrays use a minimum of 7 bytes plus the space to store an array of the data type. Two bytes are used to store the two character variable name and the data type. A 16-bit offset to the next variable: 2 bytes. One byte stores the number of dimensions, and two bytes minimum for each size of a dimension. The space required in an array for each data type is 5 bytes for each floating point, 2 bytes for each integer, and 3 bytes for each string. No space is wasted in the array. There are no arrays of defined functions.
 
Using one character variable names, and reusing variables is one way to save on space. The FRE(0) function can be used to houseclean (garbage collect) unused string space. If arrays are not declared with DIM they default to 11 elements in size. PEEK and POKE can be used to operate on byte and bit sized data.
<syntaxhighlight lang="gwbasic"> 0 CLEAR : PRINT "DATA TYPES":F = 0:F = FRE (0)
1 PRINT "FLOATING POINT:";:G = 0: GOSUB 9
2 PRINT "INTEGER:";:I0% = 0: GOSUB 9
3 PRINT "STRING:";:Z9$ = "": GOSUB 9
4 PRINT "DEFINED-FUNCTION:";: DEF FN DO(IT) = 1 + LEN ( MID$ (Z9$,1)) + IT: GOSUB 9: PRINT
5 PRINT "ARRAYS OF SIZE 1"
6 PRINT "FLOATING POINT:";: DIM F(0): GOSUB 9: PRINT "INTEGER:";: DIM I%(0): GOSUB 9: PRINT "STRING:";: DIM S$(0): GOSUB 9: PRINT
7 PRINT "ARRAYS OF SIZE 2"
8 PRINT "FLOATING POINT:";: DIM G(1): GOSUB 9: PRINT "INTEGER:";: DIM J%(1): GOSUB 9: PRINT "STRING:";: DIM T$(1): GOSUB 9: END
9 PRINT F - FRE (0)" ";:F = FRE (0): RETURN</syntaxhighlight>
<pre>
DATA TYPES
FLOATING POINT:7 INTEGER:7 STRING:7 DEFINED-FUNCTION:14
ARRAYS OF SIZE 1
FLOATING POINT:12 INTEGER:9 STRING:10
ARRAYS OF SIZE 2
FLOATING POINT:17 INTEGER:11 STRING:13
</pre>
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
The only way to 'set' the size of a scalar numeric variable is to declare it with the appropriate type suffix:
<langsyntaxhighlight lang="bbcbasic"> var& = 1 : REM Variable occupies 8 bits
var% = 1 : REM Variable occupies 32 bits
var = 1 : REM Variable occupies 40 bits
var# = 1 : REM Variable occupies 64 bits</langsyntaxhighlight>
If the task is talking about setting the size of a variable ''at run time'' that is only possible with strings, arrays and structures.
 
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 DIM A(10)
110 NUMERIC ARRAY(1 TO 100)
120 NUMERIC MATRIX(1 TO 10,1 TO 10)
130 NUMERIC NR,X,Y
140 STRING NAME$(1 TO 100)*24
150 STRING LINE$*254
160 STRING CHAR$*1</syntaxhighlight>
 
=={{header|C}}==
{{works with|C99}}
<langsyntaxhighlight lang="c">#include <stdint.h>
 
int_least32_t foo;</langsyntaxhighlight>
 
Here <var>foo</var> is a signed integer with at least 32 bits. [[wp:stdint.h#Minimum-width integer types|stdint.h]] also defines minimum-width types for at least 8, 16, 32, and 64 bits, as well as unsigned integer types.
 
<langsyntaxhighlight lang="c">union u {
int i;
long l;
double d;
/* ... */
};</langsyntaxhighlight>
 
Here the use of <code>union</code> results in a datatype which is at least as large as the largest type. Unions are sometimes exploited to just meet a minimum size:
 
<langsyntaxhighlight lang="c">union must_be_at_least_512_bytes {
int interesting_datum;
char padding[512];
};</langsyntaxhighlight>
 
Here, the application will never access <code>padding</code> nor store anything; the padding is there to make the type large enough to meet some requirement. For instance, so that some third party API function which fills in the object, doesn't write past the end of the memory, when the program is only interested in <code>interesting_datum</code>.
Line 87 ⟶ 250:
=={{header|C++}}==
{{works with|C++11}} or {{works with|Boost}}
<langsyntaxhighlight Cpplang="cpp">#include <boost/cstdint.hpp>
 
boost::int_least32_t foo;</langsyntaxhighlight>
 
Alternatively,
 
C++'s primitive types are fixed in size. If a programmer wants a numeric type to be able to accommodate
 
a certain size of number, up to a maximum of eight bytes, then they declare a variable of the appropriate type.
<syntaxhighlight lang="c++">
#include <iostream>
#include <climits>
#include <cfloat>
 
int main() {
std::cout << "The ranges of C++'s primitive data types are:" << std::endl << std::endl;
 
std::cout << "a char ranges from : " << CHAR_MIN << " to " << CHAR_MAX << std::endl;
std::cout << "a short char ranges from : " << SCHAR_MIN << " to " << SCHAR_MAX << std::endl;
std::cout << "an unsigned char ranges from : " << 0 << " to " << UCHAR_MAX << std::endl << std::endl;
 
std::cout << "a short int ranges from : " << SHRT_MIN << " to " << SHRT_MAX << std::endl;
std::cout << "an unsigned short int ranges from : " << 0 << " to " << USHRT_MAX << std::endl << std::endl;
 
std::cout << "an int ranges from : " << INT_MIN << " to " << INT_MAX << std::endl;
std::cout << "an unsigned int ranges from : " << 0 << " to " << UINT_MAX << std::endl << std::endl;
 
std::cout << "a long int ranges from : " << LONG_MIN << " to " << LONG_MAX << std::endl;
std::cout << "an unsigned long int ranges from : " << 0 << " to " << ULONG_MAX << std::endl;
std::cout << "a long long int ranges from : " << LLONG_MIN << " to " << LLONG_MAX << std::endl;
std::cout << "an unsigned long long int ranges from : " << 0 << " to " << ULLONG_MAX <<std::endl << std::endl;
 
std::cout << "a float ranges from : " << -FLT_MAX << " to " << +FLT_MAX << std::endl << std::endl;
 
std::cout << "a double ranges from : " << -DBL_MAX << " to " << +DBL_MAX << std::endl;
}
</syntaxhighlight>
{{ out }}
<pre>
The ranges of C++'s primitive data types are:
 
a char ranges from : -128 to 127
a short char ranges from : -128 to 127
an unsigned char ranges from : 0 to 255
 
a short int ranges from : -32768 to 32767
an unsigned short int ranges from : 0 to 65535
 
an int ranges from : -2147483648 to 2147483647
an unsigned int ranges from : 0 to 4294967295
 
a long int ranges from : -2147483648 to 2147483647
an unsigned long int ranges from : 0 to 4294967295
a long long int ranges from : -9223372036854775808 to 9223372036854775807
an unsigned long long int ranges from : 0 to 18446744073709551615
 
a float ranges from : -3.40282e+38 to 3.40282e+38
 
a double ranges from : -1.79769e+308 to 1.79769e+308
</pre>
 
=={{header|D}}==
In D, any variables of static array of zero length has a size of zero. But such data is useless, as no base type element can be accessed.
<langsyntaxhighlight lang="d">typedef long[0] zeroLength ;
writefln(zeroLength.sizeof) ; // print 0</langsyntaxhighlight>
NOTE: a dynamic array variable's size is always 8 bytes, 4(32-bit) for length and 4 for a reference pointer of the actual storage somewhere in runtime memory.<br>
The proper candidates of minimum size variable are empty structure, 1-byte size data type variable (include <tt>byte, ubyte, char and bool</tt>), and void, they all occupy 1 byte.
<langsyntaxhighlight lang="d">byte b ;
ubyte ub ;
char c ;
bool t ;</langsyntaxhighlight>
<tt>bool</tt> is logically 1-bit size, but it actually occupy 1 byte.<br>
<tt>void</tt> can't be declared alone, but <tt>void.sizeof</tt> gives 1.<br>
An empty structure is logically zero size, but still occupy 1 byte.
<langsyntaxhighlight lang="d">struct Empty { }
writefln(Empty.sizeof) ; // print 1</langsyntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
{In Delphi you can have variables of a range of sizes}
var B: Byte; {8-bit, unsigned}
var C: char; {ASCII character}
var SI: shortint; {8-bit, signed}
var SM: Smallint; {16-bit signed}
var LI: Longint; {32-bit signed}
var W: word; {16-bit unsigned}
var LW: Longword; {32-bit unsigned}
var II: Int64; {64-bit signed}
var SR: Real48; {6-byte real}
var SN: single; {4-byte real}
var DB: double; {8-byte real}
var EX: Extended; {10-byte real}
var CM: Comp; {8-byte fixed point}
var CR: Currency; {8-byte fixed point}
 
{You can also custom define the size range of variable}
 
type TNumRange = -128..127;
var NM: TNumRange;
 
type TUpperCase = 'A'..'Z';
var UP: TUpperCase;
 
</syntaxhighlight>
{{out}}
<pre>
 
</pre>
 
 
=={{header|Erlang}}==
Line 120 ⟶ 377:
Variable sizes are in chunks relating to the type of data that they contain. There may also be additional bytes of storage in the variable table that do not show in the dimensions. Typically, in ERRE strings are allocated in single characters (bytes), so C$[12] in the following example is stored as 12 bytes + additional bytes used for the header in the variable table. Integers are typically 2 bytes each, so A%[10] contains 10 numbers of 2 bytes (20 bytes in total) + additional bytes used for header data in the variable table. Floating point values are typically 4 bytes each, so B[10] holds 10 numbers of 4 bytes (40 bytes in total) + additional bytes for header in the variable table:
 
<syntaxhighlight lang="erre">DIM A%[10] ! the array size is 10 integers
 
DIM B[10] ! the array will hold 10 floating point values
 
DIM C$[12] ! a character array of 12 bytes</langsyntaxhighlight>
 
There is also "double" floating point values (8 bytes). Variables of this type use the suffix #.
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">
create cvar 0 c, \ char size variable
 
variable var \ cell size variable
 
2variable 2var \ 2 cells size variable
 
fvariable fvar \ float size variable
 
</syntaxhighlight>
 
=={{header|Fortran}}==
Line 138 ⟶ 407:
'''selected_int_kind(R)''', where R is the required decimal exponent range. The return value is the kind type parameter for integer values n such that -10^R < n < 10^R. A value of -1 is returned if R is out of range.
 
<langsyntaxhighlight lang="fortran">program setsize
implicit none
 
Line 180 ⟶ 449:
write(*, form) "iprec4", kind(n7), r6, range(n7)
 
end program</langsyntaxhighlight>
Output
<pre>KIND NAME KIND NUMBER PRECISION RANGE
Line 193 ⟶ 462:
iprec3 3 8 9
iprec4 4 16 18</pre>
 
=={{header|Free Pascal}}==
''See also: [[#Pascal|Pascal]]''
 
Only enumeration type definitions can have a minimum size:<syntaxhighlight lang="pascal">type
{$packEnum 4}
enum = (x, y, z);</syntaxhighlight>
Only a <tt>{$packEnum}</tt> of <tt>1</tt>, <tt>2</tt>, or <tt>4</tt> Bytes can be specified.
 
=={{header|FreeBASIC}}==
Line 210 ⟶ 487:
{{trans|Ada}}
For task interpretation this follows the spirit of the Ada example included by the task author. In it, an enumeration type is defined from enumeration values, then a storage size--smaller than the default--is specified for the type. A similar situation exists within Go. Defining types from values is called duck-typing, and the situation where a type smaller than the default can be specified exists when a variable is duck-typed from a numeric literal.
<langsyntaxhighlight lang="go">package main
 
import (
Line 234 ⟶ 511:
fmt.Println("fMin:", unsafe.Sizeof(fMin), "bytes")
fmt.Println("cMin:", unsafe.Sizeof(cMin), "bytes")
}</langsyntaxhighlight>
Output:
<pre>
Line 246 ⟶ 523:
cMin: 8 bytes
</pre>
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">
<lang Haskell>
import Data.Int
import Foreign.Storable
Line 264 ⟶ 542:
task "Int64" i64
task "Int" int
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 285 ⟶ 563:
* lists can be specified with a minimum size (see below):
 
<langsyntaxhighlight Iconlang="icon"> L := list(10) # 10 element list </langsyntaxhighlight>
 
=={{header|J}}==
 
<langsyntaxhighlight Jlang="j">v=: ''</langsyntaxhighlight>
 
Here, v is specified to have a minimum size. In this case, the minimum size of the content is zero, though the size of the representation is somewhat larger.
 
=={{header|Java}}==
Java's primitive types are fixed in size. If a programmer wants a numeric type to be able to accommodate
 
a certain size of number, up to a maximum of eight bytes, then they declare a variable of the appropriate type.
 
If more than eight bytes of precision is required they can use either BigInteger or BigDecimal.
<syntaxhighlight lang="java">
public final class VariableSizeSet {
 
public static void main(String[] args) {
System.out.println("The ranges of Java's primitive data types are:");
System.out.println();
System.out.println("A Byte variable has a range of " + Byte.MIN_VALUE + " to " + Byte.MAX_VALUE);
System.out.println("A Short variable has a range of " + Short.MIN_VALUE + " to " + Short.MAX_VALUE);
System.out.println("An Int variable has a range of " + Integer.MIN_VALUE + " to " + Integer.MAX_VALUE);
System.out.println("A Long variable has a range of " + Long.MIN_VALUE +" to " + Long.MAX_VALUE);
System.out.println("A Float variable has a range of " + Float.MIN_VALUE + " to " + Float.MAX_VALUE);
System.out.println("A Double variable has a range of " + Double.MIN_VALUE + " to " + Double.MAX_VALUE);
}
 
}
</syntaxhighlight>
{{ out }}
<pre>
The ranges of Java's primitive data types are:
 
A Byte variable has a range of -128 to 127
A Short variable has a range of -32768 to 32767
An Int variable has a range of -2147483648 to 2147483647
A Long variable has a range of -9223372036854775808 to 9223372036854775807
A Float variable has a range of 1.4E-45 to 3.4028235E38
A Double variable has a range of 4.9E-324 to 1.7976931348623157E308
</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">types = [Bool, Char, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64]
 
for t in types
Line 304 ⟶ 616:
 
println("\nFor the 24-bit user defined type MyInt24, size is ", sizeof(MyInt24), " bytes.")
</langsyntaxhighlight> {{output}} <pre>
For type Bool size is 1 8-bit bytes, or 8 bits.
For type Char size is 4 8-bit bytes, or 32 bits.
Line 325 ⟶ 637:
 
The following program shows the range of numbers which the primitive numeric types can accomodate to enable one to choose the appropriate type:
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun main(args: Array<String>) {
Line 335 ⟶ 647:
println("A Float variable has a range of : ${Float.MIN_VALUE} to ${Float.MAX_VALUE}")
println("A Double variable has a range of : ${Double.MIN_VALUE} to ${Double.MAX_VALUE}")
}</langsyntaxhighlight>
 
{{out}}
Line 347 ⟶ 659:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Mathematica stores variables in symbols : e.g. variable 'A' containing integer 0 requires 24 bytes under Windows.
 
=={{header|Modula-3}}==
<langsyntaxhighlight lang="modula3">TYPE UByte = BITS 8 FOR [0..255];</langsyntaxhighlight>
Note that this only works for records, arrays, and objects. Also note that the size in bits must be large enough to hold the entire range (in this case, 8 bits is the correct amount for the range 0 to 255) or the compiler will error.
 
=={{header|Nim}}==
1) In Nim, for base types, the size of a variable is determined by the type. There is some flexibility, as it is possible to choose the type according to the required size. For instance, for signed integers, we can choose among int8, int16, int32 and int64. The size of the variable of type “int” is 32 or 64 bits according to the platform. The same exists for unsigned integers (uint8/byte, uint16, uint32, uint64) and for floating point numbers (float32, float64/float).
<lang nim>var a: int8 = 0
 
var b: int16 = 1
2) For structured types, the size is generally fixed, except for sequences and strings. Sequences and strings are managed via a descriptor whose size is fixed (eight bytes for now). The actual data are allocated on the heap. The true size of a sequence or a string is named its capacity. The capacity is managed at runtime but the user may indicate the initial size using the procedures <code>initSeqOfCap</code> or <code>initStringOfCap</code>. For instance, <code>var s = initStringOfCap(20)</code> allocates an empty string (whose length is 0) but with the capacity to accept 20 bytes without any reallocation. If the length exceeds the capacity, the reallocation algorithm increases the capacity to a new size.
var c: int32 = 10
 
var d: int64 = 100</lang>
3) Nim offers also the possibility to set the size of fields into an object. This is done with the pragma <code>bitsize</code>. For instance, we can specify:
 
<syntaxhighlight lang="nim">type
MyBitfield = object
flag {.bitsize:1.}: cuint</syntaxhighlight>
 
When Nim uses C as intermediate language, the pragma “bitsize” is translated in C bit fields. The previous example will produce something like that:
<syntaxhighlight lang="c">struct mybitfield {
unsigned int flag:1;
};</syntaxhighlight>
 
=={{header|ooRexx}}==
Line 364 ⟶ 686:
 
=={{header|PARI/GP}}==
<syntaxhighlight lang ="parigp">default(precision, 1000)</langsyntaxhighlight>
Alternately, in the gp interpreter,
<syntaxhighlight lang ="parigp">\p 1000</langsyntaxhighlight>
 
=={{header|Pascal}}==
Pascal discourages the programmer to think about specific internal memory structures.
Ordinal and floating point types of FreePascal are listed here: [[http://www.freepascal.org/docs-html/ref/refsu5.html]] and here: [[http://www.freepascal.org/docs-html/ref/refsu6.html]]
Therefore, there is no way to specify the size of any data type.
<lang pascal>var
a: byte; // 1 byte
b: word; // 2 byte
c: cardinal; // 4 byte
d: QWord; // 8 byte
 
The GPC (GNU Pascal compiler), however, allows for ''integer'' types the specification of a minimum precision:
x: real; // 4 byte
<syntaxhighlight lang="pascal">type
y: double; // 8 byte</lang>
correctInteger = integer attribute (size = 42);</syntaxhighlight>
''See also: [[#Free Pascal|Free Pascal]]''
 
=={{header|Perl}}==
Line 383 ⟶ 703:
 
In Perl, memory is readily and happily traded for expressiveness and ease of use.
=={{header|Perl 6}}==
In Perl 6, normal user-facing types (Int, Rat, Str, Array, Hash) are all auto-sizing, so there is no need to specify a minimum size for them. (Floating point, known as "Num", defaults to a machine double.) For storage declarations, native storage types (starting with a lowercase letter) may also be specified, in which case the required bit size is part of the type name: int16, uint8 (aka "byte"), num32 (a "float"), complex64 (made of two num64's), etc. More generally, such types are created through an API supporting representational polymorphism, in this case, the NativeHOW representation, when provides methods to set the size of a type; the actual allocation calculation happens when such generic types are composed into a class instance representing the semantics of the effective type to the compiler and run-time system. But mostly this is not something users will concern themselves with directly.
 
By spec, arrays may be declared with dimensions of fixed size, but as of this writing, such arrays not yet implemented. An array of fixed size that returns elements of a native type will be stored compactly, and uses exactly the memory you'd think it should, (modulo alignment constraints between elements and any slop at the end due to your memory allocator).
 
=={{header|Phix}}==
Line 402 ⟶ 718:
When using mprf.e (aka gmp), variables can have any precision required, up to available memory.<br>
mpz (integer) variables automatically grow as needed but can optionally be initialised with a minimum bitcount to avoid later reallocations.<br>
mpfr (floating point) variables require the precision to be explicitly specified in binary bits, for example if you want PI to 1000120 decimal places:
{{libheader|Phix/mpfr}}
<lang Phix>include mpfr.e -- requires 0.8.0+
<!--<syntaxhighlight lang="phix">(phixonline)-->
string nines = repeat('9',1001) -- +1 for the "3."
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
mpz ndp = mpz_init(nines) -- mpz_init(nines,3322) would be identical
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.0"</span><span style="color: #0000FF;">)</span>
integer precision = mpz_sizeinbase(ndp,2) -- 3322
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
mpfr pi = mpfr_init(0,precision) -- or just hard-code that 3322
<span style="color: #004080;">mpfr</span> <span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">121</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 120 dp, +1 for the "3."</span>
mpfr_const_pi(pi)
<span style="color: #7060A8;">mpfr_const_pi</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span>
mpfr_printf(1,"PI with 1000 decimals: %.1000RDf\n\n",pi)</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"PI with 120 decimals: %s\n\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">mpfr_get_fixed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">120</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
 
=={{header|PicoLisp}}==
In PicoLisp, all variables have the same size (a single cell). But it is
possible to create a data structure of a given minimal size with the
'[http://software-lab.de/doc/refN.html#need need]' function.
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli">
declare i fixed binary (7), /* occupies 1 byte */
j fixed binary (15), /* occupies 2 bytes */
Line 429 ⟶ 752:
y float decimal (16), /* occupies 8 bytes */
z float decimal (33); /* occupies 16 bytes */
</syntaxhighlight>
</lang>
 
=={{header|PicoLisp}}==
In PicoLisp, all variables have the same size (a single cell). But it is
possible to create a data structure of a given minimal size with the
'[http://software-lab.de/doc/refN.html#need need]' function.
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">
<lang PureBasic>
EnableExplicit
 
Line 479 ⟶ 797:
EndIf
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 603 ⟶ 921:
=={{header|Racket}}==
Like many other highlevel languages, Racket doesn't have direct control on object sizes. More than that, objects are almost always references, so holding a vector or a list still starts from some object with pointers to the rest. It is possible, however, to create random ffi structs with some given length, by using something like <tt>(_array _byte N)</tt> and it's possible to add that to some other ffi type by wrapping it with such an array in a struct. But to create and manage chunks of memory, it's much better to just use <tt>malloc</tt> (which is also available via the ffi).
 
=={{header|Raku}}==
(formerly Perl 6)
In Raku, normal user-facing types (Int, Rat, Str, Array, Hash) are all auto-sizing, so there is no need to specify a minimum size for them. (Floating point, known as "Num", defaults to a machine double.) For storage declarations, native storage types (starting with a lowercase letter) may also be specified, in which case the required bit size is part of the type name: int16, uint8 (aka "byte"), num32 (a "float"), complex64 (made of two num64's), etc. More generally, such types are created through an API supporting representational polymorphism, in this case, the NativeHOW representation, when provides methods to set the size of a type; the actual allocation calculation happens when such generic types are composed into a class instance representing the semantics of the effective type to the compiler and run-time system. But mostly this is not something users will concern themselves with directly.
 
By spec, arrays may be declared with dimensions of fixed size, but as of this writing, such arrays not yet implemented. An array of fixed size that returns elements of a native type will be stored compactly, and uses exactly the memory you'd think it should, (modulo alignment constraints between elements and any slop at the end due to your memory allocator).
 
=={{header|REXX}}==
Line 618 ⟶ 942:
<br><br>There's effectively no limit for the precision [or length] for REXX numbers (except for memory),
<br>but eight million is probably the practical limit.
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates on setting a variable (using a "minimum var size".*/
numeric digits 100 /*default: 9 (decimal digs) for numbers*/
 
Line 628 ⟶ 952:
 
/* [↑] these #'s are stored as coded. */
/*stick a fork in it, we're all done. */</langsyntaxhighlight>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">/* Ranges for variables of the primitive numeric types */
println(s"A Byte variable has a range of : ${Byte.MinValue} to ${Byte.MaxValue}")
println(s"A Short variable has a range of : ${Short.MinValue} to ${Short.MaxValue}")
Line 637 ⟶ 961:
println(s"A Long variable has a range of : ${Long.MinValue} to ${Long.MaxValue}")
println(s"A Float variable has a range of : ${Float.MinValue} to ${Float.MaxValue}")
println(s"A Double variable has a range of : ${Double.MinValue} to ${Double.MaxValue}")</langsyntaxhighlight>
 
See it running in your browser by [https://scastie.scala-lang.org/dX0sTLz5Q1ShT8mLL0cv1g Scastie (JVM)].
Line 644 ⟶ 968:
In Tcl, most values are (Unicode) strings. Their size is measured in characters, and the minimum size of a string is of course 0.
However, one can arrange, via write traces, that the value of a variable is reformatted to bigger size. Examples, from an interactive [[tclsh]] session:
<langsyntaxhighlight Tcllang="tcl">% proc format_trace {fmt _var el op} {upvar 1 $_var v; set v [format $fmt $v]}
 
% trace var foo w {format_trace %10s}
Line 652 ⟶ 976:
% trace var grill w {format_trace %-10s}
% puts "/[set grill bar]/"
/bar /</langsyntaxhighlight>..or limit its size to a certain length:
<langsyntaxhighlight Tcllang="tcl">% proc range_trace {n _var el op} {upvar 1 $_var v; set v [string range $v 0 [incr n -1]]}
 
% trace var baz w {range_trace 2}
% set baz Frankfurt
Fr</langsyntaxhighlight>
 
=={{header|TXR}}==
Line 667 ⟶ 991:
Here, the buffer holds eight zero bytes, but 4096 bytes is allocated to it:
 
<langsyntaxhighlight lang="txrlisp">(make-buf 8 0 4096)</langsyntaxhighlight>
 
Another situation, in the context of FFI, is that some structure needs to achieve some size, but we don't care about all of its members. We can add anonymous padding to ensure that it meets the minimum size. For instance, suppose we want to call <code>uname</code>, and we only care about retrieving the <code>sysname</code>:
Line 707 ⟶ 1,031:
The last feature eliminates the need for explicitly setting the precision of numbers having exact
representations, albeit contrary to the convention in physical sciences.
<langsyntaxhighlight Ursalalang="ursala">p = mpfr..pi 200 # 200 bits of precision
 
x = mpfr..grow(1.0E+0,1000) # 160 default precision, grown to 1160
Line 717 ⟶ 1,041:
a = # 180 bits (not the default 160) because of more digits in the constant
 
1.00000000000000000000000000000000000000000000000000000E0</langsyntaxhighlight>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">fn main() {
b := true
i := 5 // default type is i32
r := '5'
f := 5.0 // default type is float64
println("b: ${sizeof(b)} bytes")
println("i: ${sizeof(i)} bytes")
println("r: ${sizeof(r)} bytes")
println("f: ${sizeof(f)} bytes")
i_min := i8(5)
r_min := `5`
f_min := f32(5.0)
println("i_min: ${sizeof(i_min)} bytes")
println("r_min: ${sizeof(r_min)} bytes")
println("f_min: ${sizeof(f_min)} bytes")
}</syntaxhighlight>
{{out}}
<pre>b: 1 bytes
i: 4 bytes
r: 16 bytes
f: 8 bytes
i_min: 1 bytes
r_min: 4 bytes
f_min: 4 bytes
 
</pre>
 
=={{header|Wren}}==
In Wren, variables are always exactly 8 bytes in size. They either store their value directly (Num, Bool or Null) or a reference (a 64 bit pointer) to where an object is stored in memory.
 
Technically, a variable always contains an 8 byte double precision floating point value but uses a technique known as 'NaN tagging' to store bools, nulls or pointers as well as numbers.
 
So there is no such thing as a minimum size for a variable or scalar type; the size of the former is always 8 bytes and of the latter however many 8 byte values are needed to store its fields.
 
Wren has four built-in collection types: String, Range, Map and List. The size of the first two is determined by their currently assigned value which is immutable but the size of the last two can change dynamically as elements are added or removed.
Of course, a variable which has been assigned values of these types is always exactly 8 bytes in size and holds a reference to where the actual object is stored on the heap,
 
The programmer cannot specify a minimum size for a Map but can specify a minimum size for a List - in effect the amount of heap storage required to store its elements. This can still be increased dynamically by adding futher elements to the List. Here's an example.
<syntaxhighlight lang="wren">// create a list with 10 elements all initialized to zero
var l = List.filled(10, 0)
// give them different values and print them
for (i in 0..9) l[i] = i
System.print(l)
// add another element to the list dynamically and print it again
l.add(10)
System.print(l)</syntaxhighlight>
 
{{out}}
<pre>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
string 0; \use zero-terminated strings
char S,
Line 732 ⟶ 1,110:
I:= I & ~(1<<29); \stores a 0 bit into bit 29 of the integer
IntOut(0, I>>3 & 1); \displays value of bit 3
]</langsyntaxhighlight>
 
Other than arrays and strings, variables are a fixed size. Integers are
four bytes and reals are eight bytes.
 
=={{header|Z80 Assembly}}==
{{trans|6502 Assembly}}
Syntax will vary depending on the assembler and whether your program will run in RAM or ROM.
For programs that execute from RAM such as those that are loaded from a disk, you can use the same syntax that you would use to define constants. When defining bytes as variables or constants, you do not prefix them with a # sign. Only in actual CPU instructions do you need to use a # to prevent the assembler from treating the numeric value as a memory location.
 
Since these are variables, the value given to them (in this case, 0) is the initial value, and can be changed later at runtime. If you don't care what the initial value is, some assemblers allow you to use a "?" where the 0s are.
 
<syntaxhighlight lang="z80">MyByte:
byte 0 ;most assemblers will also accept DB or DFB
MyWord:
word 0 ;most assemblers will also accept DW or DFW
MyDouble:
dd 0</syntaxhighlight>
 
For programs that are executed solely from ROM, such as video game console cartridges, you won't be able to use the above method. The assembler can often use an <code>enum</code> or <code>rsset</code> directive to sequentially assign labels to a series of consecutive memory locations in the system's RAM.
 
<syntaxhighlight lang="z80">.rsset $C000 ;starting at $C000, the following labels represent sequential memory locations of length ".rs n"
tempByte .rs 1
tempWord .rs 2
tempLong .rs 4</syntaxhighlight>
 
Assemblers that don't have an <code>enum</code> or <code>rsset</code> directive can use the <code>equ</code> directive instead. This method lets you immediately see what each memory location actually is, but it makes it harder to insert a new one without having to redo all the numbering. When loading from an immediate memory location to a 16-bit register pair (e.g. <code>LD HL,($4000)</code>, the "low register" is loaded with the byte stored at the memory location specified by the operand, and the "high register" is loaded with the byte stored at the memory location after that.
<syntaxhighlight lang="z80">tempByte equ $C000
tempWord equ $C001 ;high byte at $C002
tempLong equ $C003 ;you have to track spacing yourself with this method</syntaxhighlight>
 
While setting a variable's size is easy, getting it isn't possible without knowing it in advance. The CPU does not (and cannot) know the intended size of a variable. There's no enforcement of types whatsoever on the Z80, anything goes. If, for example, you executed <code>LD HL,($4000)</code> and $4000 was <i>intended</i> to be the storage location of an 8-bit value, you'd get the intended value in L and whatever happened to be after it in memory into H. Whether that's a problem or not is up to the programmer, not the CPU.
 
=={{header|zkl}}==
Line 742 ⟶ 1,148:
=={{header|ZX Spectrum Basic}}==
 
<langsyntaxhighlight lang="basic">10 DIM a$(10): REM This array will be 10 characters long
20 DIM b(10): REM this will hold a set of numbers. The fixed number of bytes per number is implementation specific
30 LET c=5: REM this is a single numerical value of fixed size</langsyntaxhighlight>
 
{{omit from|AWK}}
Line 761 ⟶ 1,167:
{{omit from|NetRexx}}
{{omit from|PlainTeX}}
{{omit from|Processing}}
{{omit from|PureBasic}}
{{omit from|Ruby}}
9,476

edits