On Sunday, October 3, 2021 at 6:31:05 PM UTC+8, ju...@diegidio.name wrote: > On Sunday, 3 October 2021 at 11:24:58 UTC+2, hongy...@gmail.com wrote: > > On Sunday, October 3, 2021 at 2:18:17 PM UTC+8, hongy...@gmail.com wrote: > > > On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name > > > wrote: > > > > On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com > > > > wrote: > > > > > See the following testings: > > > > > > > > > > In [24]: a=3.1415926535897932384626433832795028841971 > > > > > In [27]: -a > > > > > Out[27]: -3.141592653589793 > > > > You've never heard of floating-point? Double precision has 53 > > > > significant bits of mantissa, corresponding approximately to 16 decimal > > > > digits. > > > > <https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64> > > > > > > > > > In [17]: ~-+1 > > > > > Out[17]: 0 > > > > << The unary ~ (invert) operator yields the bitwise inversion of its > > > > integer argument. The bitwise inversion of x is defined as -(x+1). It > > > > only applies to integral numbers or to custom objects that override the > > > > __invert__() special method. >> > > > > <https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations> > > > > > > > A further inference based on the above description: > > > > > > Let us consider this equation: -(x+1) = x, the solution is -0.5, which is > > > not an integer. So we can safely come to a conclusion: > > > > > > If bool(a) == True, \forall a \in integer, then ~bool(a) == False; and > > > vice versa. > > > > > > This is exactly the theoretical basis to filter some specific columns in > > > pandas, just as the issue discussed here [1]. > > Sorry my not very precise description above. I should have wanted to > > express the fact that I observed below: > > In [3]: import numpy as np > > In [15]: ~np.array([True]) > > Out[15]: array([False]) > > > > In [16]: ~np.array([False]) > > Out[16]: array([ True]) > > > > But the normal `True' and `False' don't the good symmetric feature as shown > > above: > > > > In [21]: bool(~True) > > Out[21]: True > > > > In [22]: bool(~False) > > Out[22]: True > You keep missing the point: > << The unary ~ (invert) operator yields the bitwise inversion of its integer > argument. The bitwise inversion of x is defined as -(x+1). It only applies to > integral numbers or to custom objects that override the __invert__() special > method. >> > Then you can guess that numpy overrides it and gives you *logical* negation > of boolean values,
I try to dig through the numpy source code to pinning point the overriding/monkey patching/decorating code snippets, as follows: $ rg -A5 -uu 'def __invert__' . ./numpy/__init__.pyi 2022: def __invert__(self: NDArray[bool_]) -> NDArray[bool_]: ... 2023- @overload 2024: def __invert__(self: NDArray[_IntType]) -> NDArray[_IntType]: ... 2025- @overload 2026: def __invert__(self: NDArray[object_]) -> Any: ... 2027- 2028- @overload 2029- def __pos__(self: NDArray[_NumberType]) -> NDArray[_NumberType]: ... 2030- @overload 2031- def __pos__(self: NDArray[timedelta64]) -> NDArray[timedelta64]: ... -- 2885: def __invert__(self) -> bool_: ... 2886- __lshift__: _BoolBitOp[int8] 2887- __rlshift__: _BoolBitOp[int8] 2888- __rshift__: _BoolBitOp[int8] 2889- __rrshift__: _BoolBitOp[int8] 2890- __and__: _BoolBitOp[bool_] -- 2993: def __invert__(self: _IntType) -> _IntType: ... 2994- # Ensure that objects annotated as `integer` support bit-wise operations 2995- def __lshift__(self, other: _IntLike_co) -> integer: ... 2996- def __rlshift__(self, other: _IntLike_co) -> integer: ... 2997- def __rshift__(self, other: _IntLike_co) -> integer: ... 2998- def __rrshift__(self, other: _IntLike_co) -> integer: ... ./numpy/array_api/_array_object.py 510: def __invert__(self: Array, /) -> Array: 511- """ 512- Performs the operation __invert__. 513- """ 514- if self.dtype not in _integer_or_boolean_dtypes: 515- raise TypeError("Only integer or boolean dtypes are allowed in __invert__") ./numpy/lib/user_array.py 179: def __invert__(self): 180- return self._rc(invert(self.array)) 181- 182- def _scalarfunc(self, func): 183- if self.ndim == 0: 184- return func(self[0]) ./numpy/lib/mixins.pyi 62: def __invert__(self): ... Which is corresponding to the overriding mentioned above by you? > while on primitives you get the usual *arithmetic* behaviour, where > bool(~False) implicitly is bool(~int(False)) = bool(~0) = bool(-1) = True. Implicit cast happens here automatically. > Please take note: (typically!) ~ denotes a bitwise operation on integers, not > logical negation on booleans. Thank you for stressing the point again. HZ -- https://mail.python.org/mailman/listinfo/python-list