We've mentioned the types of arrays, and how to create arrays with the right type. But what happens when arrays with different types interact? For some operations, the behavior of numarray is significantly different from Numeric.
In numarray (in contrast to Numeric), there is now a distinction between how
coercion is treated in two basic cases: array/scalar operations and array/array
operations. In the array/array case, the coercion rules are nearly identical to
those of Numeric, the only difference being combining signed and unsigned
integers of the same size. The array/array result types are enumerated in
table 4.2.
Bool | Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 | |
Bool | Int8 | Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 |
Int8 | Int8 | Int16 | Int16 | Int32 | Int32 | Int64 | Int64 | Int64 | Float32 | Float64 | Complex32 | Complex64 | |
UInt8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 | ||
Int16 | Int16 | Int32 | Int32 | Int64 | Int64 | Int64 | Float32 | Float64 | Complex32 | Complex64 | |||
UInt16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 | ||||
Int32 | Int32 | Int64 | Int64 | Int64 | Float32 | Float64 | Complex32 | Complex64 | |||||
UInt32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 | ||||||
Int64 | Int64 | Int64 | Float64 | Float64 | Complex64 | Complex64 | |||||||
UInt64 | UInt64 | Float64 | Float64 | Complex64 | Complex64 | ||||||||
Float32 | Float32 | Float64 | Complex32 | Complex64 | |||||||||
Float64 | Float64 | Complex64 | Complex64 | ||||||||||
Complex32 | Complex32 | Complex64 | |||||||||||
Complex64 | Complex64 |
Scalars, however, are treated differently. If the scalar is of the same ``kind'' as the array (for example, the array and scalar are both integer types) then the output is the type of the array, even if it is of a normally ``lower'' type than the scalar. Adding an Int16 array with an integer scalar results in an Int16 array, not an Int32 array as is the case in Numeric. Likewise adding a Float32 array to a float scalar results in a Float32 array rather than a Float64 array as is the case with Numeric. Adding an Int16 array and a float scalar will result in a Float64 array, however, since the scalar is of a higher kind than the array. Finally, when scalars and arrays are operated on together, the scalar is converted to a rank-0 array first. Thus, adding a ``small'' integer to a ``large'' floating point array is equivalent to first casting the integer ``up'' to the type of the array.
>>> print (array ((1, 2, 3), type=Int16) * 2).type() numarray type: Int16 >>> arange(0, 1.0, .1) + 12 array([ 12. , 12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9]
The results of array/scalar operations are enumerated in table
4.3. Entries marked with " are identical to
their neighbors on the same row.
Bool | Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 | |
int | Int32 | Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 |
long | Int32 | Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Float32 | Float64 | Complex32 | Complex64 |
float | Float64 | " | " | " | " | " | " | " | Float64 | Float32 | Float64 | Complex32 | Complex64 |
complex | Complex64 | " | " | " | " | " | " | " | " | " | " | " | Complex64 |
The type identifiers (Float32, etc.) are NumericType instances. The mapping between type and the equivalent C variable is machine dependent. The correspondences between types and C variables for 32-bit architectures are shown in Table 4.4.
# of bytes | # of bits | Identifier |
1 | 8 | Bool |
1 | 8 | Int8 |
1 | 8 | UInt8 |
2 | 16 | Int16 |
2 | 16 | UInt16 |
4 | 32 | Int32 |
4 | 32 | UInt32 |
8 | 64 | Int64 |
8 | 64 | UInt64 |
4 | 32 | Float32 |
8 | 64 | Float64 |
8 | 64 | Complex32 |
16 | 128 | Complex64 |
type) |
>>> floatarray = otherarray.astype(Float64)
>>> print x [ 0. 0.4 0.8 1.2 300.6] >>> print x.astype(Int32) [ 0 0 0 1 300] >>> print x.astype(Int8) # wrap-around [ 0 0 0 1 44]