code: def _copy_convert(X, const=None, remove_mean=False, copy=True):
      r
      # determine type
      dtype = np.float64  # default: convert to float64 in order to avoid cancellation errors
      if X.dtype.kind == 'b' and X.shape[0] < 2**23 and not remove_mean:
          dtype = np.float32  # convert to float32 if we can represent all numbers
      # copy/convert if needed
      if X.dtype not in (np.float64, dtype):  # leave as float64 (conversion is expensive), otherwise convert to dtype
          X = X.astype(dtype, order='C')
          if const is not None:
              const = const.astype(dtype, order='C')
      elif copy:
          X = X.copy(order='C')
          if const is not None:
              const = const.copy(order='C')
  
      return X, const
docs: r""" Makes a copy or converts the data type if needed
  
      Copies the data and converts the data type if unsuitable for covariance
      calculation. The standard data type for covariance computations is
      float64, because the double precision (but not single precision) is
      usually sufficient to compute the long sums involved in covariance
      matrix computations. Integer types are avoided even if the data is integer,
      because the BLAS matrix multiplication is very fast with floats, but very
      slow with integers. If X is of boolean type (0/1), the standard data type
      is float32, because this will be sufficient to represent numbers up to 2^23
      without rounding error, which is usually sufficient sufficient as the
      largest element in np.dot(X.T, X) can then be T, the number of data points.
  
      Parameters
      ----------
      remove_mean : bool
          If True, will enforce float64 even if the input is boolean
      copy : bool
          If True, enforces a copy even if the data type doesn't require it.
  
      Return
      ------
      X : ndarray
          copy or reference to X if no copy was needed.
      const : ndarray or None
          copy or reference to const if no copy was needed.