Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c++;和具有大值的c#sin函数_C#_C++_.net_Floating Point_.net 4.7.2 - Fatal编程技术网

c++;和具有大值的c#sin函数

c++;和具有大值的c#sin函数,c#,c++,.net,floating-point,.net-4.7.2,C#,C++,.net,Floating Point,.net 4.7.2,当我使用大数时,我在C#中遇到了这种奇怪的数学行为;例如: C#:.Net 4.7.2:Math.Sin(6.2831853071795856E+45)=6.2831853071795856E+45 C++:sin(6.2831853071795856E+45)=-0.089650623841643268 有什么办法能得到与C+++< /p >相同的结果? C#样本: 双值=6.2831853071795856E+45; Console.WriteLine(Math.Sin(value));

当我使用大数时,我在C#中遇到了这种奇怪的数学行为;例如:

C#:.Net 4.7.2:Math.Sin(6.2831853071795856E+45)=6.2831853071795856E+45

C++:sin(6.2831853071795856E+45)=-0.089650623841643268

有什么办法能得到与C+++< /p >相同的结果? C#样本:

双值=6.2831853071795856E+45;
Console.WriteLine(Math.Sin(value));
C++示例:

double x=6.2831853071795856E+45;
双重结果;
结果=sin(x);
cout6.2831853071795856E+45等大数的分布;毫无意义。请记住,圆周率约为3.14,浮点数可能为(有关更多信息,请参阅)

计算出的数字可能完全错误。 考虑使用像C或C++代码这样的静态分析工具。或者像这样的动态工具

根据经验,像
sin
cos
tan
这样的三角函数不应与大数字一起使用(例如,大于π的几千倍ℼ = 绝对值为3.14)

否则,使用bignum库,如。它将使计算速度降低数千倍,但它可以为
sin(pi*1.e+45)

请阅读一些关于(它们与三角函数有关)

还可以尝试使用“可视化”函数
sin
(对于合理的数字)

从数学上讲,每个有限实数的
sin
介于-1和1之间。所以Math.Sin(6.2831853071795856E+45)=6.2831853071795856E+45是错误的


另请阅读像和这样的会议论文。

作为旁注,sin/cos/tan的计算方法在.NET中发生了变化。事件发生在2016年6月2日,发生在.NET Core上。正如作者在书中所写:

AMD64窗口上的Sin、Cos和Tan以前是在vm\AMD64\JitHelpers\u Fast.asm中实现的 调用x87浮点代码(fsin、fcos、fptan),因为CRT帮助程序太慢。这 不再如此,所有平台都使用CRT调用

请注意,CRT是C语言运行库。这解释了为什么.NET内核的更新版本在同一平台< /强>中使用与C++ +<强>相同的结果。他们正在使用与其他C++程序相同的CRT。 为感兴趣的人准备的“旧”代码的最后版本:和

尚不清楚.NET Framework是否/何时继承了这些更改。从一些测试看来

.NET核心>=2.0(尚未测试以前的版本):
Math.Sin(6.2831853071795856E+45)==0.824816390616968

.NETFramework 4.8(32位和64位):
Math.Sin(6.2831853071795856E+45)==6.28318530717959E+45

所以它没有继承他们

有趣的附录


做了一些检查,发现
Math.Sin(6.2831853071795856E+45)=6.28318530717959E+45
fsin
汇编操作码的“官方”答案,所以它是英特尔(大约1980年)关于6.2831853071795856E+45的Sin是多少的“官方”答案,所以如果你使用英特尔,你必须相信
Math.Sin(6.2831853071795856E+45)==6.28318530717959E+45,否则你就是叛徒!两个答案都大错特错,但你提出的问题可能会给你带来麻烦。

罪的真正价值(6.2831853071795856 × 10⁴⁵) 约为0.09683996046341126;此近似值与真实值相差小于10⁻¹⁶ 真实值的一部分。(我使用165位中间精度计算了这个近似值。)

但是,你不能通过C++的函数来签名,它的签名是“代码>公共静态双罪恶(双A)< />代码,或者是C++函数,签名为代码>双罪恶(double)< /代码>。为什么?6.2831853071795856 × 10⁴⁵ 不是IEEE 754二进制64或“双精度”浮点数,因此您最多只能了解附近浮点数的罪恶。最接近的浮点数,以及通常在程序中键入

6.2831853071795856E+45
得到的是6283185307179585571582855233194226059181031424,与6.283不同1853071795856 × 10⁴⁵ 28417144766805773940818968576≈ 2.84 × 10²⁸.

IEEE 754二进制64浮点数628318530717958557158285523194226059181031424与6.2831853071795856非常接近 × 10⁴⁵ 相对误差(相差小于10⁻¹⁷ 部分为真值),但绝对误差~2.84 × 10²⁸ 远超过周期2f(x)=sin(x)在正负1之间振荡,周期为2*pi,即sin(x)=sin(N*2*pi+x)

暂时忘掉编程语言,忘掉sin(),想想科学符号1.23E+45中的值是什么意思。它可以表示从1225000…(41个零)到1234999…(42个九)的任何值,即1E43个可能的整数(或者如果允许分数,则表示无限个值)

在这里,我通过使用十进制术语和精确地等于有效数字来严格定义。请在此处查找链接以了解更多信息:。我也希望我的指数算术正确,但不管怎样,其含义应该是清楚的


回到SN(),C和C++:由于纯数学函数输出每2×PI(6.28)重复,并且双精度浮点(IEEE 754位64加倍)在C和C++中只有15到17个显著的十进制数字,<强>没有输出(SN)函数可能是有意义的,因为输入值“丢失”(不精确)至少有30个有效/相关的十进制数字

您确定您的数字正确吗?首先,sin函数的返回值必须介于0和1之间…好的,如果我可以将我的观察添加到这个有趣的主题:。以及,嗯,编译器错误?以及