标准的 numpy 圆形平局打破遵循 IEEE 754 约定,将一半舍入到最接近的偶数。有没有办法指定不同的舍入行为,例如朝零舍入或朝-inf 舍入?我不是在谈论天花板或地板,我只是需要不同的平局。
问问题
1863 次
2 回答
11
NumPy 不对内部舍入模式进行任何控制。这里有两种选择:
- 使用
gmpy2
,如本答案中所述。这使您可以完全控制舍入模式,但使用gmpy2
简单的浮点数学可能比 NumPy 慢。 使用
fesetround
viactypes
手动设置舍入模式。这是特定于系统的,因为常量可能因平台而异;检查fenv.h
平台上的常量值。在我的机器上(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
于 2013-04-14T15:35:43.960 回答
0
使用开源软件 SWIG
要完成 nneonneo 的回答,如果您不想下载像 gmpy2 这样的大包,也不想使用带有 ctypes 的系统特定代码,您可以使用 C 与 SWIG 的绑定(假设您的计算机上已经有它)。
这是您需要做的(分四个步骤):
1)首先编写一个名为 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) 然后,一个文件 rnd_C.cpp
#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);
}
3)在您的终端中(如果您使用的不是python2.7版本,请在第二行替换python2.7):
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)导入库 _rounding.so 你刚刚通过在你的 python 文件的开头录音创建:
from your_path_to_rounding.so import rounding
于 2016-07-28T12:55:12.420 回答