簡體   English   中英

在 C++ 中將大型無符號浮點數舍入為整數的最佳方法是什么?

[英]What is the best way to round large unsigned floating point numbers to integers in C++?

我需要使用標准的“math.h”中點舍入行為將 64 位雙精度值舍入到我的代碼中最接近的 uint64_t。 其中一些數字具有以下屬性:

  • 大於 LLONG_MAX
  • 小於或等於 ULLONG_MAX

我注意到標准庫舍入函數沒有“無符號”版本。 此外,我懷疑當中間雙精度值太大而無法放入尾數時,人們用來執行此操作的某些技巧不再起作用。

進行這種轉換的最佳方法是什么?

我會使用std::round然后鉗制到 uint64 范圍。 您還需要決定如何處理 NaN。

std::round不會轉換為 integer。 請注意,C 和 C++ 中的內置浮點到 integer 轉換是截斷和未定義的超出范圍值。

std::round實現標准的“學校”類型舍入到最接近的 integer 中點案例向外舍入(例如round(1.5) == 2; round(-1.5) = -2 )。

當前舍入模式被忽略,這也不是 IEEE754 舍入到最接近的。 后者將使用round half to even和四舍五入打破平局的情況,以減少統計偏差。

long long人們會做這樣的事情。

double iv = std::round(val);
if (std::isnan(iv)) {
    return 0LL;
} else if (iv > LLONG_MAX)
   return LLONG_MAX;    
} else if (iv < LLONG_MIN) {
   return LLONG_MIN;
} else {
   return (long long)iv;
}

unsigned long long case 也相應完成。

double iv = std::round(val);
if (std::isnan(iv)) {
    return 0ULL;
} else if (iv > ULLONG_MAX)   // ok, if you know your values are less this can be spared of course
   return ULLONG_MAX;    
} else if (iv < 0) {
   return 0ULL;
} else {
   return (unsigned long long)iv;
}

最簡單的舍入方法是轉換為目標類型:
想象一下,你想將 2.3 舍入到 integer 根,然后你這樣做:

return (int) 2.3;

所以,一般來說,你這樣做:

return (destination_type) x;

但是,這里有一個總是向下取整的問題,正如您在這個 2.7 示例中看到的那樣:

return (int) 2.7;
=> yields 2

如果要四舍五入到最接近,需要加0.5再四舍五入:

return (int) (2.7 + 0.5);
=> yields 3

因此,當您想使用最接近的舍入來舍入到任何目標類型時,您需要:

return (destination_type) (x + 0.5);

暫無
暫無

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

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