Corbata rompiendo de redondo con adormecida.

La ruptura de la corbata redonda numérica estándar sigue la convención IEEE 754, para redondear la mitad hacia el número par más cercano. ¿Hay una manera de especificar diferentes comportamientos de redondeo, por ejemplo, redondear hacia cero o hacia -inf? No estoy hablando de techo ni de piso, solo necesito que se rompa la corbata.

NumPy no da ningún control sobre el modo de redondeo interno. Aquí hay dos alternativas:

  1. Use gmpy2 , como se describe en esta respuesta . Esto le da control total sobre el modo de redondeo, pero es probable que el uso de gmpy2 para gmpy2 matemáticas simples sea más lento que NumPy.
  2. Utilice fesetround mediante ctypes para configurar manualmente el modo de redondeo. Esto es específico del sistema porque las constantes pueden variar según la plataforma; Compruebe fenv.h para los valores constantes en su plataforma. En mi máquina (Mac OS X):

     import numpy as np import ctypes FE_TONEAREST = 0x0000 FE_DOWNWARD = 0x0400 FE_UPWARD = 0x0800 FE_TOWARDZERO = 0x0c00 libc = ctypes.CDLL('libc.dylib') v = 1. / (1<<23) print repr(np.float32(1+v) - np.float32(v/2)) # prints 1.0 libc.fesetround(FE_UPWARD) print repr(np.float32(1+v) - np.float32(v/2)) # prints 1.0000002 

Con el software de código abierto SWIG

Para completar la respuesta de nneonneo, si no desea descargar un paquete grande como gmpy2 ni usar un código específico del sistema con ctypes, puede usar un enlace de C con SWIG (asumiendo que ya lo tiene en su computadora).

Esto es lo que debe hacer (en cuatro pasos):

1) Escribe primero un archivo llamado rounding.i:

 %module rounding %{ /* Put header files here or function declarations like below */ void rnd_arr(); void rnd_zero(); void rnd_plinf(); void rnd_moinf(); void rnd_switch(); %} extern void rnd_arr(); extern void rnd_zero(); extern void rnd_plinf(); extern void rnd_moinf(); extern void rnd_switch(); 

2) Luego, un archivo rnd_C.cpp

 #include  #include  #include  void rnd_arr() { fesetround(FE_TONEAREST); } void rnd_zero() { fesetround(FE_TOWARDZERO); } void rnd_plinf() { fesetround(FE_UPWARD); } void rnd_moinf() { fesetround(FE_DOWNWARD); } void rnd_switch() { int r=fegetround(); if (r==FE_UPWARD) r=FE_DOWNWARD; else if (r==FE_DOWNWARD) r=FE_UPWARD; else fprintf(stderr,"ERROR ROUDING MODE \n"); fesetround(r); } 

3) En su terminal (si usa una versión diferente a python2.7, reemplace python2.7 en la segunda línea):

 swig -c++ -python -o rounding_wrap.cpp rounding.i g++ -fPIC -c rounding_wrap.cpp rnd_C.cpp -I/usr/include/python2.7 g++ -shared rounding_wrap.o rnd_C.o -o _rounding.so 

4) importe la biblioteca _rounding.so que acaba de crear grabando al principio de su archivo python:

 from your_path_to_rounding.so import rounding