如何使用 GMP 计算 2 ^ -18?

发布于 2024-07-11 12:27:06 字数 1024 浏览 3 评论 0 原文

令我尴尬的是,我刚刚发现向 mpz_pow_ui 提供负指数效果并不好。 (“手册确实说 unsigned long,你知道。”)对于其他 mpz_pow 函数,手册使用了我不理解的概念。 例如下面的“base^exp mod mod”:

void mpz_powm (mpz_t rop, mpz_t base, mpz_t exp, mpz_t mod) 
void mpz_powm_ui (mpz_t rop, mpz_t base, unsigned long int exp, mpz_t mod)
Set _rop_ to _base_^_exp_ mod _mod_.
Negative exp is supported if an inverse base-1 mod mod exists (see mpz_invert in Section 5.9 [Number Theoretic Functions], page 35). If an inverse doesn’t exist then a divide by zero is raised.

在下面的代码中,我需要更改什么才能使其能够处理负指数?

#define Z(x) mpz_t x; mpz_init( x );

BSTR __stdcall IBIGPOWER(BSTR p1, long p2 ) {
    USES_CONVERSION;

    Z(n1);
    Z(res);

    LPSTR sNum1 = W2A( p1 );

    mpz_set_str( n1, sNum1, 10 );

    mpz_pow_ui( res, n1, p2 );

    char * buff =  (char *) _alloca( mpz_sizeinbase( res, 10 ) + 2 );

    mpz_get_str(buff, 10, res);

    BSTR bResult = _com_util::ConvertStringToBSTR( buff );
    return bResult;
}

I've just discovered, to my embarrassment, that feeding negative exponents to mpz_pow_ui doesn't work very well. ("The manual does say unsigned long, you know.") For the other mpz_pow functions, the manual uses concepts I don't understand. For example "base^exp mod mod" in the following:

void mpz_powm (mpz_t rop, mpz_t base, mpz_t exp, mpz_t mod) 
void mpz_powm_ui (mpz_t rop, mpz_t base, unsigned long int exp, mpz_t mod)
Set _rop_ to _base_^_exp_ mod _mod_.
Negative exp is supported if an inverse base-1 mod mod exists (see mpz_invert in Section 5.9 [Number Theoretic Functions], page 35). If an inverse doesn’t exist then a divide by zero is raised.

In the following code, what do I have to change to make it able to handle negative exponents?

#define Z(x) mpz_t x; mpz_init( x );

BSTR __stdcall IBIGPOWER(BSTR p1, long p2 ) {
    USES_CONVERSION;

    Z(n1);
    Z(res);

    LPSTR sNum1 = W2A( p1 );

    mpz_set_str( n1, sNum1, 10 );

    mpz_pow_ui( res, n1, p2 );

    char * buff =  (char *) _alloca( mpz_sizeinbase( res, 10 ) + 2 );

    mpz_get_str(buff, 10, res);

    BSTR bResult = _com_util::ConvertStringToBSTR( buff );
    return bResult;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

耳根太软 2024-07-18 12:27:07

如果满足以下条件,则支持负 exp
逆基 1 mod mod 存在(参见
第 5.9 节中的 mpz_invert [数量
理论函数],第 35 页)。 如果
逆元不存在则除以
零被提高。

如果你谈论这个,那就涉及数论。 除法,或更准确地说是乘法的逆运算,仅在某些条件下存在。 我不太清楚规则,但基本上它是说如果 base-1 mod mod 不存在,除法运算将不起作用。

Negative exp is supported if an
inverse base-1 mod mod exists (see
mpz_invert in Section 5.9 [Number
Theoretic Functions], page 35). If an
inverse doesn’t exist then a divide by
zero is raised.

If you're talking about that, that's involves number theory. Division, or more precisely inverse of multplication, only exists on certain conditions. I don't exactly remember the rules, but basically it's saying that the division operation won't work if base-1 mod mod doesn't exist.

不语却知心 2024-07-18 12:27:07

您需要做什么取决于您希望如何处理操作中丢失的位。 由于您正在处理整数,因此提高到负幂意味着除法(好吧,倒数),但 GMP 提供了多种形式的 划分

What you need to do depends on what you want to happen with the bits that will lost in the operation. Since you are dealing with integers, raising to a negative power implies division (well, reciprocation), but GMP offers several forms of division.

儭儭莪哋寶赑 2024-07-18 12:27:06

我不会为您删除代码,但我会让您知道:

2-n = 1/2n

因此,您可以只传递正指数,然后将 1 除以该数字(并选择一个非整数类型,例如 mpf_t - mpz_t 类型是整数,因此不能表示实数,如 2-18)。

I won't cut the code for you but I will make you aware that:

2-n = 1/2n

So you can just pass the positive exponent then divide 1 by that number (and choose a non-integer type like mpf_t - the mpz_t type is integral so cannot represent real numbers like 2-18).

星軌x 2024-07-18 12:27:06

mpz_t 数据类型只能存储整数,而 2-18 不是整数。 要计算该值,您必须使用浮点类型 mpf_t 或有理数类型 mpq_t

The mpz_t data type can only store integers, and 2-18 is not an integer. To calculate that, you'll have to use the floating-point type mpf_t or the rational number type mpq_t.

A君 2024-07-18 12:27:06

我对 GMP 不太了解,但是:

2 ^ -18

相当于:

1 / (2 ^ 18)

那么为什么不编写一个以这种方式处理负指数的函数呢?

I don't know much about GMP but:

2 ^ -18

is equivalent to:

1 / (2 ^ 18)

So why not write a function that handles negative exponents in this way?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文