用numpy打破圆形

时间:2013-04-14 15:11:23

标签: python numpy scipy rounding

标准的numpy圆形打破符合IEEE 754惯例,向最近的偶数舍入一半。有没有办法指定不同的舍入行为,例如朝零或朝-inf?我不是在谈论天花板或地板,我只是需要不同的打破平局。

2 个答案:

答案 0 :(得分:10)

NumPy不对内部舍入模式进行任何控制。这有两种选择:

  1. 使用gmpy2中列出的gmpy2。这使您可以完全控制舍入模式,但使用fesetround进行简单浮点运算可能比NumPy慢。
  2. 通过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)

使用开源软件SWIG

要完成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