首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#,Modulo运算给出了与计算器不同的结果

C#,Modulo运算给出了与计算器不同的结果
EN

Stack Overflow用户
提问于 2018-03-23 18:21:05
回答 2查看 217关注 0票数 1

所以我想写一个方法: 142^23 (mod 187),使用任何计算器我得到结果65,但是用这段代码:double number = Math.Pow(142, 23) % 187我得到了53的结果。为什么,我在这里做错什么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-23 18:29:03

Math.Pow(142, 23)太大了,无法精确地用双人表示。所以你的模数是在有耗的计算上做的。

这将给出正确的答案:

代码语言:javascript
运行
复制
BigInteger.ModPow(142, 23, 187);

BigInteger可以在System.Numerics命名空间和程序集中找到。

如果您想要的话,您也可以自己高效地实现这一点,对于您在问题中使用的大小的整数来说。

代码语言:javascript
运行
复制
private static int ModPow(int basenum, int exponent, int modulus)
{
    if (modulus == 1)
    {
        return 0;
    }
    int result = 1;
    for (var i = 0; i < exponent; i++)
    {
        result = (result * basenum) % modulus;
    }
    return result;
}

BigInteger用二进制指数做了一些更聪明的事情,这将对真正庞大的数字更好地工作。

票数 11
EN

Stack Overflow用户

发布于 2018-03-23 19:34:44

如果我们使用BigInteger来计算指数的全部结果:

代码语言:javascript
运行
复制
var bi = BigInteger.Pow(142, 23);
Debug.WriteLine(bi);

我们得到了一个非常大的数字:

代码语言:javascript
运行
复制
31814999504641997296916177121902819369397243609088
or
3.1814999504642E+49

如果我们然后将该值转换为double,则会导致精度下降,然后返回到BigInteger

代码语言:javascript
运行
复制
var d = (double) bi;
bi = new BigInteger(d);
Debug.WriteLine(bi);

我们得到:

代码语言:javascript
运行
复制
31814999504641997296916177121902819369397243609088  -- BigInteger
31814999504641993108158684988768059669621048868864  -- BigInteger -> double -> BigInteger
                ^ oh no mah precision

在十六进制中,精度损失更为明显:

代码语言:javascript
运行
复制
15C4 C9EB 18CD 25CE 858D 6C2D C3E5 D319 BC9B 8000 00
15C4 C9EB 18CD 2500 0000 0000 0000 0000 0000 0000 00   
                 ^ oh no mah precision

您会注意到,精度损失发生在十七个小数位,或者十四个十六进制数字。

为什么?

is stored using IEEE-754 encoding

代码语言:javascript
运行
复制
Significand or mantissa:          0-51
Exponent:                         52-62
Sign (0 = Positive, 1 = Negative) 63

这里的关键是尾数的52位。我们的14位十六进制数字是56位,接近52位限制.我们怎么解释这个4位差异呢?

(我想我在下面的解释中犯了一个错误。如果有人能指出,我将不胜感激)

最后一个不变的十六进制数字是C,或二进制的1100;因为最后两个位是零,所以我们的数字是用54位编码的,而不是56位。所以,这实际上是一个2位的差异。

我们如何解释最后两部分呢?这是由于如何确定IEEE-754的分数分量。我已经很久没有这样做了,所以我将把它作为一个练习留给读者:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49456119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档