Tie Breaking Of Round With Numpy
Solution 1:
NumPy doesn't give any control over the internal rounding mode. Here's two alternatives:
- Use
gmpy2
, as outlined in this answer. This gives you full control over the rounding mode, but usinggmpy2
for simple float math is likely to be slower than NumPy. Use
fesetround
viactypes
to manually set the rounding mode. This is system-specific because the constants may vary by platform; checkfenv.h
for the constant values on your platform. On my machine (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) printrepr(np.float32(1+v) - np.float32(v/2)) # prints 1.0 libc.fesetround(FE_UPWARD) printrepr(np.float32(1+v) - np.float32(v/2)) # prints 1.0000002
Solution 2:
With the open-source software SWIG
To complete nneonneo answer, if you don't want to download a big package like gmpy2 neither use a system-specific code with ctypes, you can use a binding from C with SWIG (assuming that you already have it on your computer).
Here is what you need to do (in four steps):
1) Write first a file named rounding.i :
%module rounding
%{
/* Put header files here or function declarations like below */voidrnd_arr();
voidrnd_zero();
voidrnd_plinf();
voidrnd_moinf();
voidrnd_switch();
%}
externvoidrnd_arr();
externvoidrnd_zero();
externvoidrnd_plinf();
externvoidrnd_moinf();
externvoidrnd_switch();
2) Then, a file rnd_C.cpp
#include<stdio.h>#include<stdlib.h>#include<fenv.h>voidrnd_arr(){
fesetround(FE_TONEAREST);
}
voidrnd_zero(){
fesetround(FE_TOWARDZERO);
}
voidrnd_plinf(){
fesetround(FE_UPWARD);
}
voidrnd_moinf(){
fesetround(FE_DOWNWARD);
}
voidrnd_switch(){
int r=fegetround();
if (r==FE_UPWARD)
r=FE_DOWNWARD;
elseif (r==FE_DOWNWARD)
r=FE_UPWARD;
elsefprintf(stderr,"ERROR ROUDING MODE \n");
fesetround(r);
}
3) In your terminal (if you use another version than python2.7, replace python2.7 at the second line ):
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) import the library _rounding.so that you just created by taping at the beginning of your python file :
from your_path_to_rounding.soimport rounding
Post a Comment for "Tie Breaking Of Round With Numpy"