标准的numpy圆形打破符合IEEE 754惯例,向最近的偶数舍入一半。有没有办法指定不同的舍入行为,例如朝零或朝-inf?我不是在谈论天花板或地板,我只是需要不同的打破平局。
答案 0 :(得分:10)
NumPy不对内部舍入模式进行任何控制。这有两种选择:
gmpy2
中列出的gmpy2
。这使您可以完全控制舍入模式,但使用fesetround
进行简单浮点运算可能比NumPy慢。通过ctypes
使用fenv.h
手动设置舍入模式。这是系统特定的,因为常量可能因平台而异;检查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
以获取平台上的常量值。在我的机器上(Mac OS X):
{{1}}
答案 1 :(得分:0)
要完成nneonneo的答案,如果您不想下载像gmpy2这样的大包,既不使用带有ctypes的系统特定代码,您可以使用C与SWIG的绑定(假设您已经在计算机上使用它) )。
以下是您需要做的事情(分为四个步骤):
1)首先写一个名为rounding.i的文件:
SELECT *
FROM
OPENROWSET('ADSDSOObject','adsdatasource'; 'domain.com.io\test';'the_sha1_pass',
'SELECT givenname
FROM ''LDAP://domain.com.io/ou=Users,
dc=domain,dc=com,dc=io'' WHERE givenname = ''Test''
')
2)然后,文件rnd_C.cpp
%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();
3)在你的终端中(如果使用的是python2.7以外的其他版本,请在第二行替换python2.7):
#include <stdio.h>
#include <stdlib.h>
#include <fenv.h>
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);
}
4)通过在python文件的开头录制来导入刚刚创建的库_rounding.so:
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