using System;
public class Test
{
public static void Main()
{
Console.WriteLine(Math.Cos(1e27));
}
}
从某个值Math.Cos
开始,Math.Sin
开始在[-1,+ 1]段内返回其参数而不是值。例如,上面的输出是
1E+27
为什么会这样,是否有可能解决这种问题?
答案 0 :(得分:4)
三角函数函数(<javac encoding="iso-8859-1" ...>
,Sin
等)周期为 2 pi (Cos
)。但是,由于2 * Math.PI
为Math.PI
,因此仅 16-17正确的数字,您无法通过天真计算double
(我们至少需要 27位):
1e27
要执行此任务,您需要先获得适当的 Double result = Math.Cos(1e27); // totally wrong.
值,例如从这里
我们也必须与pi
合作:
BigInteger
最后,实际结果是
-0.695977596990354
注意,天真的 C ++计算(取自 Qwertiy 评论, int exponent = 27;
const String piString = "314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054";
BigInteger pi2 = BigInteger.Parse(piString) * 2;
int scale = piString.Length - 1; // 2 * pi is not that big integer, it's 6.28...
BigInteger argument = BigInteger.Pow(10, exponent + scale);
// Now let's compute the double value (fraction) that's reminder of 1e27 % (2 * PI)
String remainder = (argument % pi2)
.ToString()
.PadLeft(piString.Length, '0')
.Insert(1, "."); // we can have x.xxx, 0.xxx, 0.0xxx etc. remainders
Double fraction =
Double.Parse("0." + remainder.Substring(0, 20), CultureInfo.InvariantCulture);
// and now, finally
Double result = Math.Cos(fraction);
)是完全错误的,因为即使是C ++ 0.849247
也没有t支持double
27位数。
答案 1 :(得分:2)
角度a必须是弧度。乘以Math.PI / 180将度数转换为弧度。
可接受的范围大约为-9223372036854775295 至大约9223372036854775295.对于此之外的值 范围,Sin方法返回一个不变的而不是抛出一个 异常。
答案 2 :(得分:0)
&#34;角度d必须是弧度。乘以Math.PI / 180将度数转换为弧度。 可接受的d值范围从大约-9223372036854775295到大约9223372036854775295.对于超出此范围的值,Cos方法返回d而不是抛出异常。&#34;
参考 - &gt; https://msdn.microsoft.com/en-us/library/system.math.cos(v=vs.110).aspx
答案 3 :(得分:0)
这里的问题是Sin,Cos计算的数学和表示存储信息的可用位数,实际值。
要计算Cos函数,例如您在此处所要求的,您需要计算:
Cos(x) = 1 - x*x/2! + x*x*x*x/4! - x*x*x*x*x*x/6! + ...
如果您的号码在左侧(负)或右侧(正)限制用于存储号码的数据类型的边界,那么您可以快速解决问题,因为如果您接近此限制,那么计算x ^ 2, x ^ 4,x ^ 6在数据类型限制之外非常快......
当然,有一些方法可以选择一些不那么暴力的算法来计算Sin / Cos,但是有一些限制。
这里的第二件事是,在更长的时间内,数学计算要归功于这样的行为容易且容易出错。如果方法不介意计算结果,那么它应该以一个例外结束,以提供失败的信息。我看到了许多算法,(有些是我的:)),这些细节被忽略了,产生了神奇的结果,最终得到了NaN或类似的东西,返回相同的值。在复杂算法中使用数字,限制等来捕获这些数学错误非常困难......