我寫了一個數學函式作為我的優化演算法中的基準函式。
public static double SolomonFunction(double[] x)
{
double f;
double sum = 0;
for (int i = 0; i < x.Length; i )
{
sum = x[i] * x[i];
}
f = 1 - Math.Cos(2 * Math.PI * Math.Sqrt(sum)) 0.1 * Math.Sqrt(sum);
return f;
}
但是當輸入是SolomonFunction(new double[] { -4.74641638144941E 151, -6.49440696607247E 153, -1.0998592442531E 153, 3.58027097738642E 149, 6.28490996716059E 152 })
在控制臺應用程式中,結果6,616968044816507E 152
在 Windows 應用程式中,結果是-4,09139395927863E 154
我需要在 Windows 應用程式中做一些我不需要在控制臺應用程式中做的事情嗎?還是我從根本上誤解了什么?
uj5u.com熱心網友回復:
在產生“-4,09139395927863E 154”的平臺中,Math.Cos例程被破壞。它顯然使用了不支持 [?2 ?63 , 2 ?63 ] 之外的運算元的處理器指令。
由于我不使用 C#,因此這是一個重現正確行為的 C 程式:
#include <math.h>
#include <stdio.h>
static double SolomonFunction(size_t length, double *x)
{
double sum = 0;
for (int i = 0; i < length; i )
sum = x[i] * x[i];
return 1 - cos(2 * M_PI * sqrt(sum)) 0.1 * sqrt(sum);
}
#define NumberOf(a) (sizeof (a) / sizeof *(a))
int main(void)
{
double x[] = { -4.74641638144941E 151, -6.49440696607247E 153, -1.0998592442531E 153, 3.58027097738642E 149, 6.28490996716059E 152 };
printf("%.16g\n", SolomonFunction(NumberOf(x), x));
}
在 macOS 10.14.6 上使用 Apple Clang 11 運行時,會產生“6.616968044816507e 152”。查看計算,我們可以看到sum一定很大,結果應該完全由0.1 * Math.Sqrt(sum). 由于 [?1, 1] 中實數的余弦范圍,1 - Math.Cos(…)因此公式的一部分應該具有可忽略不計的影響,無論 的引數如何Math.Cos。所以這似乎是一個合理的結果。
考慮到另一個結果“-4,09139395927863E 154”,我們看到公式在正確計算時不可能產生負結果。1 - Math.Cos(…)應該在 [0, 2] 中,并且0.1 * Math.Sqrt(sum)永遠不應該是負數,所以它們的總和應該是非負數。
這個不正確的結果完全可以用一個有缺陷的來解釋Math.Cos。假設,當引數很大時,Math.Cos回傳它的引數而不是它的余弦。我們可以用上面的 C 代碼重現這一點,方法是使用return 1 - (2 * M_PI * sqrt(sum)) 0.1 * sqrt(sum);, wherecos已被洗掉,只留下它的引數。運行此程式會產生輸出“-4.091393959278625e 154”,與報告的輸出匹配(四舍五入到不同的位數),確認假設。
FCOS這與指令的行為一致。英特爾 64 和 IA-32 架構軟體開發人員手冊,合卷,2017 年 12 月,第 906 頁,用于FCOS:
如果源運算元超出可接受范圍,則設定 FPU 狀態字中的 C2 標志,并且暫存器 ST(0) 中的值保持不變。
Thus, when the cosine argument is out of the supported range (?263 to 263), executing FCOS leaves the argument in the register that is also used for the result. Then Math.Cos apparently uses this value for the result.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/424812.html
標籤:C# 数学 .net-core 浮点 视觉工作室 2019
上一篇:遞回創建組合串列
