簡體   English   中英

如何獲得最佳的准確結果?

[英]How can I get the best accurate result?

鑒於:

unsigned int a, b, c, d;

我想要:

d = a * b / c;

並且(a * b)可能溢出; (b / c)也可能等於零,並且准確性較低。

也許強制轉換為64位可以使事情正常進行,但是我想知道在d中獲得最准確結果的最佳方法。

有什么好的解決辦法嗎?

我會:

  • 強制轉換為64位(如果適用於您的a,b和c范圍)。
  • 使用像GMP這樣的無限精度庫
  • 如果發現這些結果可以接受,則轉換為floatdouble float並返回。

為了獲得最佳的准確性/精度,您需要在除法之前進行乘法。 就像您暗示的那樣,您將需要使用比int兩倍多的位:

int64_t d = (int64_t) a * (int64_t) b;
d /= c;

您不需要兩個強制轉換,但可以說它們使內容更加清晰。

請注意,如果c足夠小,則d仍可以大於int。 這可能對您來說不是問題。 如果您確定不是,則可以在末尾強制轉換為int。

使用浮點數或雙精度數,在浮點運算中, 允許除以零 ,結果將為正無窮大

您始終可以對* b上的溢出進行顯式檢查:

long long e = (long long) a * (long long) b;
if (e <= INT_MAX) {
    d = e / c;
} else {
    d = a * (b / c);
}

當然,這僅適用於非負a,b,c。 如果它們可以是負數,則還必須對照INT_MIN。

[更新]您還可以檢查a和b中的哪一個較大,從而除以c會降低精度:

if (a >= b) {
    d = a / c * b;
} else {
    d = a * (b / c);
}

對於您所說的問題,我會做d = (long long)a * b / c;

當您只需要更多位時,就沒有float意義。 無需重新聲明或投射所有內容。 強制轉換a足以在表達式中將bc提升為更大的尺寸。

我會按照以下方式做一些事情:

if(c){
    d = (long long)a * b;
    d /= c;
}
else{
    // some error code because div by 0 is not allowed
}

為什么不使用floatdouble float float (在Intel芯片上)是一個32位浮點數,因此您不一定需要64位操作嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM