# Data Types > [HTML Version](datatypes.htm) _Updated July 2024_ ASB supports the data types shown in the tables below. **Scalar Types** | **Type** | **Code** | **Size** | **Description** | |------|------|------|------| | Floating Point | F | 4 | Single precision IEEE float, ~7 significant digits | | | F | 6 | 48 bit (WD16, M68000, AMOS) float, ~11 significant digits | | | F | 8 | double precision IEEE float, ~16 significant digits | | Unsigned Integer (little-endian byte order) | B | 1 | 8 bit unsigned | | | B | 2 | 16 bit unsigned | | | B | 3 | 24 bit unsigned | | | B | 4 | 32 bit unsigned | | | B | 5 | 40 bit signed (two's complement) | | | B | 6 | 48 bit signed (two's complement, little-endian) | | Signed Integer | I | 1 | 8 bit signed (two’s complement) | | | I | 2 | 16 bit signed (two’s complement, little-endian); see [Boolean](#booleandatatype) below | | | I | 4 | 32 bit signed (two’s complement, 2301 order) | | | I | 6 | 48 bit signed (two's complement); see [B6 and I6 Variables](#b6andi6variables) below | | String | S | \# | fixed length string of # bytes; see [String Variables](#stringvariables) below | | | S | 0 | variable length string; see [Dynamically Sized Variables](dynamically-sized_variables.htm.md) | | Unformatted
(raw bytes) | X | 0 | fixed length raw bytes | | | X | 0 | variable length raw bytes; see [Dynamically Sized Variables](dynamically-sized_variables.htm.md) | | | (none) | | Size determined by lower-level [MAP](mapstatements.htm.md) declarations. | **Compound or Structure Types** | **Type** | **Example** | **See Note #** | |------|------|------| | Multi-level MAPs | MAP1 CUST
MAP2 NAME,S,30
MAP2 CUSNO,B,4
MAP2 TOTSALES,F,6
READ #CH, CUST \! read/write entire group as a unit
? NAME \! individual fields referenced by name | 1, 2 | | [DEFSTRUCT](defstruct.htm.md) | DEFSTRUCT ST\_CUST \! define structure layout
MAP2 NAME,S,30
MAP2 CUSNO,B,4
MAP2 TOTSALES,F,6
ENDSTRUCT
...
MAP1 CUSREC,ST\_CUST \! define instance of structure
...
READ #CH, CUSREC \! read/write entire struct at once
? CUSREC.NAME \! use structvar.member notation for fields | | | [DYNSTRUCT](dynamicstructures.htm.md) | MAP1 DS, DYNSTRUCT | | Table Notes: 1 Also known as "records", the multi-level MAP arrangement is physically equivalent a [DEFSTRUCT](defstruct.htm.md), except for the syntax of accessing its members. Programmers are encouraged to use DEFSTRUCT as it makes the code more self-documenting and simplifies creating multiple instances and arrays of the layout. 2 Any MAPn level with higher-numbered levels defined within it. **See Also** • [BINDSTRUCT](bind_a_dynstruct.htm.md) **(./images/hmtoggle_plus0.gif) B6 and I6 Variables** ****B,6 and I,6 variables—little endian 48 bit unsigned and signed integers, respectively—were added to ASB in A-Shell version 6.3.1516.0 and compiler edit 763. They are not supported under AMOS. These extend the range of integers that can be stored properly as integers to nearly as great as the range of integers that can be represented precisely by the F,8 data type. The range of B,5 variables is just slightly less than the corresponding range of integers that can be stored precisely in the F,6 data type. B,6 and I,6 variables can be used like any other numeric variables in statements, expressions, parameter passing, etc., with the following reminders: • Beware that A-Shell run-time versions prior to 6.3.1516 will not properly deal with programs containing B,6 or I,6 variables. Earlier versions of the compiler will report the problem clearly—?Illegal size for variable type—but the run-time will simply misinterpret any values held in those variables, probably treating the value as 0. • As with any conversion between types, when converting from B,6 or I,6 to other types, the receiving variable must be large enough to hold the converted value, else the result will be truncated, wrapped, or otherwise corrupted without any error condition being raised. For B,6 and I,6, the only other data types that can hold the entire range of possible values are F,8 and S,15+. In the case of string, you must set SIGNIFICANCE 15 to avoid exponential notation for large values. • As with any conversion from a floating point value to an integer variable, the fractional part will be truncated, and if the source value exceeds the range of the destination variable type, the result will be wrapped around, without any error being raised. • See [ashinc:minmax.def](https://bitbucket.org/microsabio/soslib/src/master/907016/minmax.def) for definitions of the minimum and maximum integer values that can be held by each integer type. • Bitwise operators (AND, OR, NOT, XOR, EQV) operate out to 48 bits. • Built-in subroutines, while having access to the new extended range of integers, have not necessarily been updated to take advantage of them. Unless the documentation explicitly indicates otherwise, you should assume a 32 bit limit for general numeric parameters. • Decimal, octal, and hex constants and symbol definitions support values extending to 48 bit integer or F8 floating point; previously it was 40 bit integer or F6 floating point. You may optionally append an "L" to the end of such literal constants to make explicit that you want them to be encoded into the RUN file using the larger format, but this isn't necessary as the compiler will do it automatically as needed. • The functions Fn'Dec2Hex\$() and Fn'Hex2Dec() in [SOSLIB:\[907,10\]](https://bitbucket.org/microsabio/soslib/src/master/907010/?at=default) have been updated to support the new 48 bit integers. Make sure to download and recompile with the updated fndec2hex.bsi and/or fnhex2dec.bsi modules if you plan to use these functions with values larger than 32 bit values. **(./images/hmtoggle_plus0.gif) String Variables** ****ASB strings are similar to strings in other languages, although there are a few quirks that are worth special attention: • **ANSI**: In other words, one byte per character—unlike, say, UNICODE or Wide strings. Typically the Latin1 encoding is used: standard ASCII for the low 7 bits, with the upper range used for certain accented characters and symbols common in the most popular Western and Latin-derived languages. But there is nothing preventing you from using other encodings such as UTF8, or XML encoding, provided there are no embedded null bytes, and provided that you handle the necessary conversions for printing and other uses. • **Fixed vs Variable Length**: String variables may either be declared as fixed length (e.g. S,25) or variable length by specifying length zero (S,0). Fixed length strings are not only fixed in length but also in position relative to other variables, which is particularly important for mapped structures mirroring data records made up of fixed length fields. Variable length (aka dynamic) strings will move around in memory as they shrink and grow, so should not be used within fixed structures. See [Dynamically Sized Variables](dynamically-sized_variables.htm.md) for more details. • **Termination**: String variables are either terminated logically by the first null byte, or physically, by filling up the allotted space in a fixed size variable. Conceptually it shouldn't matter, as the terminator is effectively added as needed when performing operations. But when passing string variables to subroutines embedded within A-Shell (written in C) or to external libraries (using DYNLIB), you may be responsible for providing your own explicit null terminators if the variable was full and is immediately followed by another in memory, as within a structure. Most standard subroutines handle this detail internally—check the documentation if uncertain—but virtually no external libraries will, because in most other languages, the assumption is that strings are always explicitly terminated by a null byte. • **Logical vs Physical Length**: As just noted, when a fixed length string contains an explicit null terminator, the logical length of the string variable, as measured by the LEN() function, will be shorter than the physical length, as measured by the [.SIZEOF()](sizeof().htm.md) function. The difference between the logical and physical length is generally not of interest for most operations, except when making assignments directly to a substring. See [Substring Operator](substringoperator.htm.md) for more details. This is not applicable to variable length strings. • **Trailing Blanks**: Trailing blanks are significant when it comes to display, printing, concatenation, substring operations, etc. But the one glaring exception is that they are not considered significant when comparing two strings—variables or expressions. This exception applies only to blanks, i.e. ASCII 32, and not to other any non-printing characters such as tabs, carriage returns, etc. If you want to distinguish between two strings that differ only in the number of trailing blanks, you have to take into account the string length. • **X vs S variables**: The X (unformatted) data type behaves similarly to S (string), and a string variable can always be copied to an X variable and back again without any loss. Note that the reverse is not true. The main difference between the two types is that for strings, a null byte marks the logical end of the data, whereas for X variables, nulls bytes are handled just like any other bytes. The logical end of the data is determined solely by the physical length of the variable. In the case of dynamic X variables, the logical and physical length is always the same. **(./images/hmtoggle_plus0.gif) Boolean** ****Although BOOLEAN is an alias for I,2 (signed integer), declared in ashinc:types.def, it is intended to store only two possible values: .TRUE (-1) or .FALSE (0). .TRUE and .FALSE are system-defined dot variables. Note that an IF test will treat any non-zero value in any numeric variable type or expression as logically true, but using the BOOLEAN type and .TRUE (instead of, say, 1) to indicate logical truth allows for the NOT operator to work both arithmetically (flipping all the bits) and logically (flipping true and false), as expected. **See Also** • [Boolean Bitwise Arithmetic](booleanbitwisearithmetic.htm.md)