[英]What is the best way to round large unsigned floating point numbers to integers in C++?
我需要使用標准的“math.h”中點舍入行為將 64 位雙精度值舍入到我的代碼中最接近的 uint64_t。 其中一些數字具有以下屬性:
我注意到標准庫舍入函數沒有“無符號”版本。 此外,我懷疑當中間雙精度值太大而無法放入尾數時,人們用來執行此操作的某些技巧不再起作用。
進行這種轉換的最佳方法是什么?
我會使用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.