首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >对于C#中的不同.NET版本,模运算符(%)给出不同的结果

对于C#中的不同.NET版本,模运算符(%)给出不同的结果
EN

Stack Overflow用户
提问于 2014-01-31 13:53:03
回答 4查看 8.1K关注 0票数 88

我正在对用户的输入进行加密,以生成密码字符串。但是一行代码在框架的不同版本中给出了不同的结果。用户按下键值的部分编码:

按键: 1.变量ascii为49。经过计算后的'e‘和'n’的值:

代码语言:javascript
运行
AI代码解释
复制
e = 103, 
n = 143,

Math.Pow(ascii, e) % n

上述代码的结果:

.NET 3.5中的

  • (C#)

Math.Pow(ascii,e) %n

提供9.0.

  • In .NET 4 (C#)

Math.Pow(ascii,e) %n

提供77.0.

Math.Pow()在两个版本中都给出了正确(相同)的结果。

原因是什么?有解决方案吗?

EN

回答 4

Stack Overflow用户

发布于 2014-01-31 14:04:10

你看到的是双精度的舍入误差。Math.Pow使用double,不同之处如下:

.NET 2.0和3.5 => var powerResult = Math.Pow(ascii, e);返回:

代码语言:javascript
运行
AI代码解释
复制
1.2308248131348429E+174

.NET 4.0和4.5 => var powerResult = Math.Pow(ascii, e);返回:

代码语言:javascript
运行
AI代码解释
复制
1.2308248131348427E+174

注意E前面的最后一个数字,这是导致结果不同的原因。这不是模运算符,(%)

票数 26
EN

Stack Overflow用户

发布于 2014-01-31 14:00:13

浮点精度因机器和even on the same machine而异。

然而,.NET为你的应用程序创建了一个虚拟机...但是不同的版本会有所不同。

因此,您不应该依赖它来产生一致的结果。对于加密,请使用Framework提供的类,而不是使用自己的类。

票数 23
EN

Stack Overflow用户

发布于 2014-02-01 11:56:24

关于代码糟糕的方式,有很多答案。然而,对于为什么结果是不同的…

英特尔的FPUs在内部使用80位格式,以获得更精确的中间结果。因此,如果一个值在处理器寄存器中,它将获得80位,但当它被写入堆栈时,它将被存储在64位中。

我希望新版本的.NET在它的即时编译中有一个更好的优化器,所以它在寄存器中保留一个值,而不是将值写入堆栈,然后从堆栈中读回它。

可能JIT现在可以在寄存器中返回值,而不是在堆栈中返回值。或者将该值传递给寄存器中的MOD函数。

另请参阅堆栈溢出问题

其他处理器,例如ARM,将对此代码给出不同的结果。

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

https://stackoverflow.com/questions/21481764

复制
相关文章

相似问题

领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档