C++ std::isnan等函數的使用


C和C++11標准提供了類似於isnan、isfinite、isinf、isnormal、fpclassify分別用於判斷是非數(NaN)值、有限制、無窮值、正常數值等。
今天在使用Modbus讀取設備對應寄存器的float狀態值時,出現一些問題,導致數據不能正常獲取,最后發現原來設備對應的寄存器里面會出現一些無效的值,導致讀取顯示出錯,沒做容錯判斷處理。后面加上條件判斷就可以了。

bool D02011C01::getState()
	{
		bool rc = false;
		Modbus::RTU rtu;
		// 獲取工況參數(共12項)
		Uint8Array req = rtu.req(deviceId(), 4, 1110, 24);
		if (SendCmd(rtu, req, 3000, 3))
		{
			float xishu[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
			for (int i = 0; i < 12; i++)
			{
				float val;
				// 獲取的val值可能不是有效的float類型,比如說:-1.#IND,需要對所獲取的結果做有效性判斷
				if (rtu.get_value(val, 2 * i, false, false) && !std::isnan(val))
				{
					setStateData(i + 1, val);
					rc = true;
				}
			}
		}

		return rc;
	}

注意
對於float類型的值,C和C++11中都做了相應的處理,用於判斷一個float值是否為無窮大、非數( NaN )值;

有多個擁有不同符號位和載荷的不同 NaN 值,參閱 std::nan 及 std::numeric_limits::quiet_NaN 。

NaN 值決不與自身或其他 NaN 值比較相等。 IEEE-754 不要求復制 NaN 保留其位表示(符號與載荷),盡管大多數實現保留。

另一種測試浮點值是否 NaN 的方式是與自身比較: bool is_nan(double x) { return x != x; }
示例如下:

#include <iostream>
#include <cmath>
#include <cfloat>
 
int main()
{
    std::cout << std::boolalpha
              << "isnan(NaN) = " << std::isnan(NAN) << '\n'
              << "isnan(Inf) = " << std::isnan(INFINITY) << '\n'
              << "isnan(0.0) = " << std::isnan(0.0) << '\n'
              << "isnan(DBL_MIN/2.0) = " << std::isnan(DBL_MIN/2.0) << '\n'
              << "isnan(0.0 / 0.0) = " << std::isnan(0.0/0.0) << '\n'
              << "isnan(Inf - Inf) = " << std::isnan(INFINITY - INFINITY) << '\n';
}

輸出:

isnan(NaN) = true
isnan(Inf) = false
isnan(0.0) = false
isnan(DBL_MIN/2.0) = false
isnan(0.0 / 0.0)   = true
isnan(Inf - Inf)   = true

有時候發現不少函數以前沒怎么用過,遇到問題才發現又學到了一些知識。
C和C++11標准提供了類似於isnan、isfinite、isinf、isnormal、fpclassify分別用於判斷是非數(NaN)值、有限制、無窮值、正常數值等。

isnan
NAN
Not-A-Number (constant )
isfinite
Is finite value (macro )
isinf
Is infinity (macro/function )
isnormal
Is normal (macro/function )
fpclassify
Classify floating-point value (macro/function )

參考資料:
1、https://zh.cppreference.com/w/cpp/numeric/math/isnan
2、https://en.cppreference.com/w/cpp/numeric/math/isnan
3、http://www.cplusplus.com/reference/cmath/isnan/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM