當雙精度縮小為浮點數時,我收到一些 -Wnarrowing 轉換錯誤。我怎樣才能以明確定義的方式做到這一點?最好使用模板中的選項,我可以切換行為,從拋出例外到限制到最接近的值,或簡單的截斷。我正在查看gsl::narrow演員表,但它似乎只是在幕后執行靜態演員表和后續比較:Understanding gsl::narrow implementation。我想要一些更健壯的東西,正如C 程式員應該知道的所有常見未定義行為是什么? static_cast<>如果值在目標型別中不可表示,則為 UB。我也很喜歡這個實作,但它也依賴于static_cast<>:double 中分配給 double 的 static_cast<float> 是否可以優化掉?我不想為此使用升壓。還有其他選擇嗎?如果這在 c 03 中有效是最好的,但是 c 0x(experimental c 11) 也是可以接受的……或者如果真的需要的話 11……
因為有人問,這里有一個簡單的玩具示例:
#include <iostream>
float doubleToFloat(double num) {
return static_cast<float>(num);
}
int main( int, char**){
double source = 1; // assume 1 could be any valid double value
try{
float dest = doubleToFloat(source);
std::cout << "Source: (" << source << ") Dest: (" << dest << ")" << std::endl;
}
catch( std::exception& e )
{
std::cout << "Got exception error: " << e.what() << std::endl;
}
}
我的主要興趣是向 doubleToFloat(...) 添加錯誤處理和安全性,如果需要,可以使用各種自定義例外。
uj5u.com熱心網友回復:
只要您的浮點型別可以存盤無窮大(極有可能),就不可能存在未定義的行為。您可以測驗std::numeric_limits<float>::has_infinity是否真的想確定。
用于static_cast使警告靜音,如果你想檢查溢位,你可以這樣做:
template <typename T>
bool isInfinity(T f) {
return f == std::numeric_limits<T>::infinity()
|| f == -std::numeric_limits<T>::infinity();
}
float doubleToFloat(double num) {
float result = static_cast<float>(num);
if (isInfinity(result) && !isInfinity(num)) {
// overflow happened
}
return result;
}
任何double未溢位的值都將被精確轉換或轉換為兩個最接近的float值之一(可能是最接近的)。您可以使用 顯式設定舍入方向std::fesetround。
uj5u.com熱心網友回復:
這取決于你所說的“安全”是什么意思。在大多數情況下,精度很可能會下降。你想檢測是否發生這種情況?斷言,還是只知道它并通知用戶?
一種可能的解決方案是將 double 靜態轉換為 float,然后再轉換為 double,然后比較之前和之后。平等是不可能的,但你可以斷言精度損失在你的容忍范圍內。
float doubleToFloat(double a_in, bool& ar_withinSpec, double a_tolerance)
{
auto reducedPrecision = static_cast<float>(a_in);
auto roundTrip = static_cast<double>(reducedPrecision);
ar_withinSpec = (roundTrip < a_tolerance);
return reducedPrecision;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/534079.html
上一篇:概念中的隱式轉換
