c++ - 大整数和 double 之间的乘法

标签 c++ c++11 integer double gmp

我正在使用 gmp 管理一些大的(128~256 位)整数。我想将它们相乘得到一个接近于 1 (0.1 < double < 10) 的双倍数,结果仍然是一个近似整数。下面是我需要执行的操作的一个很好的示例:

int i = 1000000000000000000 * 1.23456789

我在 gmp 文档中进行了搜索,但没有找到相关函数,因此我最终编写了这段看起来运行良好的代码:

mpz_mult_d(mpz_class & r, const mpz_class & i, double d, int prec=10) {
  if (prec > 15) prec=15; //avoids overflows
  uint_fast64_t m = (uint_fast64_t) floor(d);
  r = i * m;
  uint_fast64_t pos=1;
  for (uint_fast8_t j=0; j<prec; j++) {
    const double posd = (double) pos;
    m = ((uint_fast64_t) floor(d * posd * 10.)) -
        ((uint_fast64_t) floor(d * posd)) * 10;
    pos*=10;
    r += (i * m) /pos;
  }
}

你能告诉我你的想法吗?您有什么建议可以让它更健壮或更快吗?

最佳答案

这就是你想要的:

// BYTE lint[_N]   ... lint[0]=MSB, lint[_N-1]=LSB
void mul(BYTE *c,BYTE *a,double b)  // c[_N]=a[_N]*b
    {
    int i; DWORD cc;
    double q[_N+1],aa,bb;
    for (q[0]=0.0,i=0;i<_N;)        // mul,carry down
        {
        bb=double(a[i])*b; aa=floor(bb); bb-=aa;
        q[i]+=aa; i++;
        q[i]=bb*256.0;
        }
    cc=0; if (q[_N]>127.0) cc=1.0;  // round
    for (i=_N-1;i>=0;i--)           // carry up
        {
        double aa,bb;
        cc+=q[i];
        c[i]=cc&255;
        cc>>=8;
        }
    }

_N 是每个大整数的位数/8,大整数是 _N BYTE 的数组,其中第一个字节是 MSB(最高有效字节),最后一个字节是 LSB(最低有效字节) 函数不处理 signum,但它只是一个 if 和一些要添加的 xor/inc。

麻烦的是即使你的数字 1.23456789 double 的精度也很低!!!由于精度损失,结果并不准确(1234387129122386944 而不是 1234567890000000000)我认为我的代码比你的代码更快甚至更精确,因为我不需要将 mul/mod/div 数字乘以 10,而是我使用在可能的情况下进行位移,而不是 10 位,而是 256 位(8 位)。如果您需要比使用长算法更高的精度。您可以通过使用更大的数字(16,32, ... 位)来加速此代码

我用于精确天文计算的长算术通常是定点 256.256 位数字,由 2*8 DWORDs + signum 组成,但当然要慢得多,而且一些测角函数很难实现,但如果你只想要基本函数,而不是编写自己的 lon 算法并不难。

此外,如果您希望数字经常以可读形式出现,则最好在速度/大小之间做出妥协,并考虑不使用二进制编码数字,而是使用 BCD 编码数字

关于c++ - 大整数和 double 之间的乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16773417/

相关文章:

c++ - 关于使用auto进行成员函数指针类型推断的问题

c++ - 如何返回类型列表中最大的类型?

c++ - 在不创建参数对象的情况下解析 constexpr 函数

c++ - 检测程序集是否可用

c# - 可空类型 "int?"(包括问号)的默认值是多少?

java - 如何在Java中计算整数表达式

arrays - MIPS-读取整数错误

c++ - C++ 中的多态性为什么不起作用?

c++ - Visual Studio C++ : Getting Unresolved tokens and unresolved link. 我该怎么办?

c++ - 1000LL 中的 LL 是什么意思?