Quoting from a numpy discussion list:
That information is available via
numpy.finfo()andnumpy.iinfo():In [12]: finfo('d').max Out[12]: 1.7976931348623157e+308 In [13]: iinfo('i').max Out[13]: 2147483647 In [14]: iinfo('uint8').max Out[14]: 255
Link here.
Answer from perimosocordiae on Stack OverflowQuoting from a numpy discussion list:
That information is available via
numpy.finfo()andnumpy.iinfo():In [12]: finfo('d').max Out[12]: 1.7976931348623157e+308 In [13]: iinfo('i').max Out[13]: 2147483647 In [14]: iinfo('uint8').max Out[14]: 255
Link here.
You can use numpy.iinfo(arg).max to find the max value for integer types of arg, and numpy.finfo(arg).max to find the max value for float types of arg.
>>> numpy.iinfo(numpy.uint64).min
0
>>> numpy.iinfo(numpy.uint64).max
18446744073709551615L
>>> numpy.finfo(numpy.float64).max
1.7976931348623157e+308
>>> numpy.finfo(numpy.float64).min
-1.7976931348623157e+308
iinfo only offers min and max, but finfo also offers useful values such as eps (the smallest number > 0 representable) and resolution (the approximate decimal number resolution of the type of arg).
You could discard the bottom 16 bits:
n=(array_int32>>16).astype(np.int16)
which will give you this:
array([ 485, 1054, 2531], dtype=int16
The numbers in your array_int32 are too large to be represented with 16 bits (a signed integer value with 16 bits can only represent a maximum value of 2^16-1=32767).
Apparently, numpy just sets the resulting numbers to zero in this case.
This behavior can be modified by changing the optional casting argument of astype The documentation states
Starting in NumPy 1.9, astype method now returns an error if the string dtype to cast to is not long enough in ‘safe’ casting mode to hold the max value of integer/float array that is being casted. Previously the casting was allowed even if the result was truncated.
So, an additional requirement casting='safe' will result in a TypeError, as the conversion from 32 (or 64) bits downto 16, as the maximum value of original type is too large for the new type, e.g.
import numpy as np
array_int32 = np.array([31784960, 69074944, 165871616])
array_int16 = array_int32.astype(np.int16, casting='safe')
results in
TypeError: Cannot cast array from dtype('int64') to dtype('int16') according to the rule 'safe'
min_value = np.iinfo(im.dtype).min
max_value = np.iinfo(im.dtype).max
docs:
np.iinfo(machine limits for integer types)np.finfo(machine limits for floating point types)
You're looking for numpy.iinfo for integer types. Documentation here.
There's also numpy.finfo for floating point types. Documentation here.
The MATLAB output has saturated at intmin('int16') = -32768 (docs), i.e. the most negative value it can represent as an int16 variable.
Python has the same range for int16 (docs), but instead of saturating at the most negative value it has experienced underflow, wrapping around to the top of the range
k = round(-3.406578165491512e+04) = -34066
k = k + (32768*2) = 31470
You could get around this by enforcing whichever of these is your preferred behaviour when the inputs are still floating point values, and then when the input is within the range -32768 to 32767 you can cast it to int16.
Wolfie gets at the difference, this is about how to solve it. If you're OK with clipping, then you can use iinfo to get the min and max values of an integer type (or hard-code it, if you know you won't be changing it from int16 ever) and then use clip to constrain the float to be within those bounds before casting it.
n = -3.406578165491512e+04
ii = np.iinfo(np.int16)
print(f"min = {ii.min}") # min = -32768
print(f"max = {ii.max}") # max = 32767
np.int16(np.clip(n, ii.min, ii.max))
# -32768
IMPORTANT NOTE: This is only reliable if the size if your float is larger than the size of the int, because it relies upon being able to represent ii.max exactly as a float. See here for a discussion of when this is not true.
Here's an example of that failing
n = np.float64(1e100)
ii = np.iinfo(np.int64)
print(f"max: {ii.max}") # max = 9223372036854775807
clipped = np.clip(n, ii.min, ii.max)
print(f"clipped to: {int(clipped)}") # clipped to: 9223372036854775808
print(f"as int: {np.int64(clipped)}") # as int: -9223372036854775808
(This happens because ii.max cannot be represented as a float. Past 9007199254740992, we lose the 1's place of precision and can only specify even integers, so the bounds of the clipping become incorrect.)