2 回答

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超6個贊
此行為是由于使用abs
,一個與 一起使用的函數(shù)int
,并向其傳遞double
參數(shù)引起的。sdouble
被隱式轉(zhuǎn)換為int
,在比較它們之前截斷小數(shù)部分。從本質(zhì)上講,這意味著您采用原始數(shù)字,去除符號,然后去除小數(shù)點(diǎn)右側(cè)的所有內(nèi)容并比較這些值。所以8.123
和-8.9
都轉(zhuǎn)換為8
, 比較相等。由于減法的輸入是相反的,因此排序是按幅度降序排列的。
您的cpp.sh
輸出反映了這一點(diǎn);所有大小在 8 和 9 之間的值首先出現(xiàn),然后是 3-4s,然后是 2-3s、1-2s 和小于 1 的值。
如果您想修復(fù)此問題以實(shí)際按一般降序排序,則需要一個正確使用-friendly函數(shù)的double
fabs
比較函數(shù),例如
int comp(const void *a, const void* b)
{ SensorIndex* x = (SensorIndex*)a;
SensorIndex* y = (SensorIndex*)b;
double diff = fabs(y->value) - fabs(x->value);
if (diff < 0.0) return -1;
return diff > 0;
}
更新:進(jìn)一步閱讀,看起來std::abs
from<cmath>
已經(jīng)與double
s 一起工作了很長時間,但std::abs
for s 僅在 C++17 中double
添加到<cstdlib>
(整數(shù)函數(shù)所在的位置)。而且實(shí)施者總是把這些東西弄錯,所以不同的編譯器會隨機(jī)表現(xiàn)不同。無論如何,這里給出的兩個答案都是正確的;如果您沒有包含并且您使用的是 C++17 之前的編譯器,則您應(yīng)該只能訪問基于整數(shù)的版本(或from ),這將在比較之前截斷每個值。即使您使用的是正確的,將減法的結(jié)果返回為abs
<cmath>
std::abs
::abs
math.h
std::abs
double
int
會丟棄 difference 的小數(shù)部分,使幅度差異小于的任何值1.0
看起來相等。更糟糕的是,根據(jù)執(zhí)行的特定比較及其排序(因?yàn)椴⒎撬兄刀枷嗷ケ容^),這種效果的后果可能會連鎖,因?yàn)楸容^排序更改可能會使看起來等于,而反過來又會1.0
看起來等于1.6
,2.5
即使如果將它們相互比較,1.0
則被正確識別為小于;2.5
理論上,只要每個數(shù)字與其他數(shù)字的差值在 1.0 以內(nèi),比較的結(jié)果就好像它們彼此相等(病態(tài)情況是的,但肯定會發(fā)生較小的此類錯誤)。
關(guān)鍵是,弄清楚這段代碼的真正意圖的唯一方法是弄清楚它最初編譯的確切編譯器版本和 C++ 標(biāo)準(zhǔn),并在那里進(jìn)行測試。

TA貢獻(xiàn)1788條經(jīng)驗(yàn) 獲得超4個贊
您的比較功能中存在錯誤。你返回 anint這意味著你失去了絕對差異小于 的元素值之間的區(qū)別!1
int comp(const void* a, const void* b)
{
SensorIndex* x = (SensorIndex*)a;
SensorIndex* y = (SensorIndex*)b;
// what about differences between 0.0 and 1.0?
return abs(y->value) - abs(x->value);
}
您可以這樣修復(fù)它:
int comp(const void* a, const void* b)
{ SensorIndex* x = (SensorIndex*)a;
SensorIndex* y = (SensorIndex*)b;
if(std::abs(y->value) < std::abs(x->value))
return -1;
return 1;
}
一種更現(xiàn)代(也更安全)的方法是使用std::vectorand std::sort:
// use a vector for dynamic arrays
std::vector<SensorIndex> s_tmp;
for(int i = 0; i < 200; ++i) {
s_tmp.push_back({q[i], i});
}
// use std::sort
std::sort(std::begin(s_tmp), std::end(s_tmp), [](SensorIndex const& a, SensorIndex const& b){
return std::abs(b.value) < std::abs(a.value);
});
- 2 回答
- 0 關(guān)注
- 135 瀏覽
添加回答
舉報