如何在.NET中执行具有较大长结果的Power?

时间:2016-09-20 09:46:16

标签: .net math

最近试图解决程序中的错误,并意识到问题出现在下面的代码中(类型不是字节,但假设这个问题不能大于那个,因为某些组合可能导致在溢出中):

long GetValue(byte x, byte y, byte z) {
  return (long)Math.Pow(x, y) * z;
}

给出示例值:x = 27,y = 12,z = 7

然后:

a = 27 ^ 12 = 150,094,635,296,999,121
r = a * 7 = 1,050,662,447,078,993,847

但是,C#.NET代码将给出:

a = 27 ^ 12 = 150,094,635,296,999,136
r = a * 7 = 1,050,662,447,078,993,952

线索在Math.Pow函数中,表示返回为:

1.5009463529699914E+17

这是因为Math.Pow函数仅对双精度存在,并且双精度具有超出某个小数值的不精确度。由于结果接近long.MaxValue,不精确的浮点数学会影响演员阵容产生的长值。

longs没有等效的Math.Pow函数。有些东西告诉我借口是因为在引擎盖下,无论你如何表达,长音和双音都是64位数。但是(在我看来)多头不应该使用浮点数学。

这是否意味着CPU无法使用32位以上的非小数值执行精确计算?这对我来说似乎非常不可能,因为Windows计算器可以使这个数学运算正确。

如何在.NET中解决这样的问题?我有点假设我在某个地方错过了一个功能。

(最初的问题是我通过改变解决方案设计的方法而不再需要这个代码来解决,但我认为我发布了这个问题,因为它很有趣。)

此致 罗布。

1 个答案:

答案 0 :(得分:0)

您可以使用function bodyRotate() { var angleX = 0, angleY = 0, angleZ = 0; var incX = -1, incY = -1, incZ = -1; var xStop = -180, yStop = -180, zStop = -180; var timerID = window.setInterval(function () { angleX += incX; angleY += incY; angleZ += incZ; var angle = "rotateX(_X_deg) rotateY(_Y_deg) rotateZ(_Z_deg)"; angle = angle.replace("_X_", angleX).replace("_Y_", angleY).replace("_Z_", angleZ) $("body").css({ "transform": angle }); if (angleX < xStop && angleY < yStop && angleZ < zStop) { incX *= -1; incY *= -1; incZ *= -1; } if (angleX > 0 && angleY > 0 && angleZ > 0) { window.clearInterval(timerID); $("body").css({ "transform": "rotateX(0deg) rotateY(0deg) rotateZ(0deg)" }); } }, 10); } $(document).ready(bodyRotate); 类来处理任意精度整数。这是解决问题的规范解决方案。

如果您不需要大于BigInteger的数字,您也可以为自己写一个天真的幂函数。

CPU使用固定大小的整数。任意大小的整数是一种软件解决方案。