第十三章 Caché 函數大全 $DOUBLE 函數 第十三章 Caché 函數大全 $DOUBLE 函數 大綱 描述 INF 與 NAN JSON數字 示例

第十三章 Caché 函數大全 $DOUBLE 函數

返回轉換爲64位浮點值的數字。

大綱

$DOUBLE(num)

參數

  • num 要轉換的數值。還可以指定字符串“NAN”和“INF”(及其變體)。

描述

$DOUBLE返回一個轉換爲IEEE雙精度(64位)浮點數據類型的數字。這種類型的浮點數最多可以包含20位數字。轉換爲IEEE雙精度(64位)浮點數據類型。如果num的位數超過20位,則$DOUBLE將小數部分四捨五入爲合適的位數。如果num的整數部分大於20個數字,則$DOUBLE將整數四捨五入爲20個有效數字,並用零表示其他數字。

$DOUBLE將Caché浮點數轉換爲IEEE雙精度浮點數。 $DECIMAL執行逆運算,將IEEE雙精度浮點數轉換爲標準Caché浮點數。

$DOUBLE生成符合IEEE雙精度(64位)二進制浮點標準的浮點數值。它主要用於與使用此數據類型標準的應用程序互換和兼容。 IEEE浮點數使用二進制表示法表示。它們具有53個二進制位的精度,對應於15.95個十進制數字。 (請注意,二進制表示形式並不完全對應於小數部分。)

與標準Caché浮點數相比,IEEE浮點數的最小/最大值範圍更大。但是,標準的Caché浮點數具有更高的精度。在大多數情況下,最好使用標準Caché浮點數。

注意:超出Caché浮點數據類型(例如“1E128”)支持的最小/最大範圍的Caché數字字符串文字將自動轉換爲IEEE雙精度浮點數。此轉換僅在數字文字上執行;它不是對數學運算的結果執行的。可以使用%SYSTEM.Process類的TruncateOverflow()方法在每個進程的基礎上控制此自動轉換。可以通過設置Config.Miscellaneous類的TruncateOverflow屬性來建立系統範圍的默認行爲。

num值可以指定爲數字或數字字符串。解析爲規範形式(刪除了前導零和尾隨零,解析了多個正負號,等等)。在$DOUBLE轉換之前。爲num指定非數字字符串將返回0。爲num指定混合數字字符串(例如“7dwarves”或“7.5.4”)會截斷第一個非數字字符的輸入值,然後轉換數字部分。提供給JSON數組或JSON對象的$DOUBLE數值遵循不同的驗證和轉換規則。

CachéSQL數據類型DOUBLE和DOUBLE PRECISION表示IEEE浮點數; FLOAT數據類型表示標準的Caché浮點數。

均等比較和混合算法

由於$DOUBLE生成的數字將轉換爲與十進制數字不完全對應的二進制表示形式,因此$DOUBLE值與標準Caché浮點數值之間的相等比較可能會產生意外結果,通常應避免這樣做。$DOUBLE值和標準Caché浮點數值之間的比較可以精確地執行,而無需四捨五入。

包含$DOUBLE值和一個或多個標準Caché編號的混合算術運算將返回$DOUBLE值。在混合算術中,Caché在執行算術運算之前會自動將所有數字轉換爲$DOUBLE值。 Caché處理與$DOUBLE數字表示之間的轉換以及數字表示之間的比較;因此,這些操作在所有平臺上都是相同的。但是,涉及$DOUBLE值的算術運算由基礎操作系統控制,因此有時在平臺之間可能有所不同。

整數除法

對於某些值,Caché十進制浮點數和IEEE雙精度數會產生不同的整數除積。例如:

DHC-APP> WRITE !,"Cache  /: ",4.1/.01           // 410
 
Cache  /: 410
DHC-APP>WRITE !,"Double /: ",$DOUBLE(4.1)/.01  // 410
 
Double /: 409.99999999999994316
DHC-APP>WRITE !,"Cache  \: ",4.1\.01           // 410
 
Cache  \: 410
DHC-APP>WRITE !,"Double \: ",$DOUBLE(4.1)\.01  // 409
 
Double \: 409

平臺獨立性

標準Caché十進制浮點數($DECIMAL數字)的精度約爲18.96十進制數字。 Caché支持的所有系統平臺的精度都是一致的。

IEEE雙精度浮點數($DOUBLE數)具有獨立於平臺的標準內部表示形式。

在Caché支持的所有系統平臺上,$DOUBLE$DECIMAL號之間的轉換和比較是一致的。但是,基於系統平臺,對$DOUBLE編號的其他計算可能會顯示細微的差異。

INF 與 NAN

按照IEEE標準,$DOUBLE可以返回字符串INF(無窮大)和NaN(不是數字)。Inf可以是正的或負的(INF-INF);NaN始終是無符號的。雖然這些是有效的IEEE返回值,但它們不是實際數字。

INF和NAN作爲輸入值

導致$DOUBLE返回INFNAN的一種方法是將相應的字符串指定爲num輸入值。這些輸入字符串不區分大小寫,並且可以帶正負號(INF解析符號,NAN忽略符號)。要返回NAN,請指定“NAN”,“ sNAN”,“ + NAN”,“-NAN”。要返回INF,請指定“ INF”,“ + INF”,“ Infinity”。要返回-INF,請指定“ -INF”,“ +-INF”

IEEEError

IEEEError控制$DOUBLE如何響應無法解析的數字轉換。如果IEEEError設置爲0,則$DOUBLE無法解析轉換時將返回INFNAN。如果IEEEError設置爲1,則$DOUBLE在無法解析轉換時會生成標準的Caché錯誤代碼。預設值爲1。

可以使用%SYSTEM.Process類的IEEEError()方法在每個進程的基礎上控制此行爲。可以通過設置Config.Miscellaneous類的IEEEError屬性來建立系統範圍的默認行爲。

返回 INF 與 NAN

當指定一個非常大的數字或指定一個不可解析的算術運算時,$DOUBLE可以返回INFNAN。僅當將IEEEError設置爲返回INFNAN時,才返回這些值。

不支持極大的浮點數。DOUBLE二進制浮點數的最大支持值爲1.7976931348623158079e308$DOUBLE二進制浮點數的最小支持值爲1.0E-323。小於此數值的num返回0。

注意:Caché十進制浮點數的最大支持值爲9.223372036854775807e145。 Caché十進制浮點數的最小支持值爲2.2250738585072013831e-308(常規)或4.9406564584124654654417e-324(非規範化)。

下表顯示了不可解析的算術運算返回的值或產生的錯誤:

輸入值 IEEEError=0 IEEEError=1
> 1.0E308 INF <MAXNUMBER>
< 1.0E-323 0 0
1/$DOUBLE(0) INF <DIVIDE>
1/$DOUBLE(–0) –INF <DIVIDE>
$DOUBLE(1)/0 INF <DIVIDE>
$DOUBLE(0)/0 NAN <ILLEGAL VALUE>
$ZLOG($DOUBLE(0)) –INF <DIVIDE>

比較INF和NAN

可以將INF視爲數值進行比較。因此,INF = INFINF'= –INF–INF = –INF,並且INF> –INF

不能將NAN視爲數值進行比較。因爲不能使用數值運算符來有意義地比較NAN(非數字),所以Caché運算(例如,等於,小於或大於)試圖將$DOUBLE(“NAN”)與另一個$DOUBLE(“NAN”)進行比較。失敗。與NAN <=> =的比較是一種特殊情況。

$LISTSAME確實認爲$DOUBLE(“NAN”)列表元素與另一個$DOUBLE(“NAN”)列表元素相同。

ISVALIDENUM,NUMBER和$FNUMBER

這些ObjectScript函數支持$DOUBLE數字。

$ISVALIDNUM支持INFNAN。儘管這些字符串不是數字,但是$ISVALIDNUM對於這些值返回1,就像它們是數字一樣。當用非數字字符串指定$DOUBLE時,例如$DOUBLE(“”),Caché返回值0。因此,$ISVALIDNUM($DOUBLE(“”)))返回1,因爲0是一個數字。

$INUMBER$FNUMBER提供支持$DOUBLE值的“D”格式選項。$INUMBER將數字轉換爲IEEE浮點數。$FNUMBER“D”支持包括INFNAN的大小寫轉換,以及選擇$DOUBLE(-0)應該返回0還是-0。

INF和NAN與操作符

可以對INFNAN執行算術和邏輯運算。不建議將操作符與INFNAN一起使用;如果執行了這樣的操作,則結果如下:

算術運算符:

加法 減法 乘法 除法(/\#運算符)
NAN+NAN=NAN NAN-NAN=NAN NAN*NAN=NAN NAN/NAN=NAN
NAN+INF=NAN NAN-INF=NAN NAN*INF=NAN NAN/INF=NAN
INF-NAN=NAN INF/NAN=NAN
INF+INF=INF INF-INF=NAN INF*INF=INF INF/INF=NAN

邏輯運算符:

等於(= NAN INF
NAN 0 0
INF 0 1
小於 (<) 或大於 (>) NAN INF
NAN 0 0
INF 0 0

其他運算符(如模式匹配和串聯)將NaNINF視爲三個字符的字母字符串。

INF and NAN 示例

$DOUBLE在數值超出可用精度時返回INF值(如果是負數,則返回-INF),如下例所示:

/// d ##class(PHA.TEST.Function).double()
ClassMethod double()
{
    SET rtn=##class(%SYSTEM.Process).IEEEError(0)
    SET x=$DOUBLE(1.2e300)
    WRITE !,"Double: ",x
    WRITE !,"Is number? ",$ISVALIDNUM(x)
    SET y= $DOUBLE(x*x)
    WRITE !,"Double squared: ",y
    WRITE !,"Is number? ",$ISVALIDNUM(y)
}

DHC-APP>d ##class(PHA.TEST.Function).double()
 
Double: 1200000000000000063100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Is number? 1
Double squared: INF
Is number? 1

$DOUBLE在數值無效時返回NaN(非數字)值。例如,當算術表達式涉及兩個INF值時,如下例所示。(涉及單個INF值的算術表達式返回INF。)

/// d ##class(PHA.TEST.Function).double1()
ClassMethod double1()
{
    SET rtn=##class(%SYSTEM.Process).IEEEError(0)
    SET x=$DOUBLE(1.2e500)
    WRITE !,"Double: ",x
    WRITE !,"Is number? ",$ISVALIDNUM(x)
    SET y= $DOUBLE(x-x)
    WRITE !,"Double INF minus INF: ",y
    WRITE !,"Is number? ",$ISVALIDNUM(y)
}
DHC-APP>d ##class(PHA.TEST.Function).double1()
 
Double: INF
Is number? 1
Double INF minus INF: NAN
Is number? 1

JSON數字

數字文字的JSON驗證在set命令中描述。在JSON數組或JSON對象中指定的$DOUBLE數字文字受以下附加規則的約束:

  • Inf-INFNaN值可以存儲在JSON結構中,但不能由%ToJSON()返回。嘗試這樣做會導致<ILLEGAL VALUE>錯誤,如下例所示:
/// d ##class(PHA.TEST.Function).double2()
ClassMethod double2()
{
    SET jary=[123,($DOUBLE("INF"))]  // executes successfully
    WRITE jary.%ToJSON()            // fails with <ILLEGAL VALUE> error
}

DHC-APP>d ##class(PHA.TEST.Function).double2()
[123,INF]

$DOUBLE(-0)以-0.0的形式存儲在JSON結構中。$Double(0)作爲0存儲在JSON結構中。下面的示例顯示了這一點:

/// d ##class(PHA.TEST.Function).double3()
ClassMethod double3()
{
    SET jary=[0,-0,($DOUBLE(0)),($DOUBLE(-0))] 
    WRITE jary.%ToJSON()  // returns [0,-0,0,-0.0]
}
DHC-APP>d ##class(PHA.TEST.Function).double3()
[0,-0,0,0]

示例

下面的示例返回20位浮點數:

DHC-APP>WRITE !,$DOUBLE(999.12345678987654321)
 
999.12345678987651353
DHC-APP>WRITE !,$DOUBLE(.99912345678987654321)
 
.99912345678987657393
DHC-APP>WRITE !,$DOUBLE(999123456789.87654321)
 
999123456789.87658691

以下示例將pi的值作爲$DOUBLE值和標準Caché數值返回。此示例表明,不應在$DOUBLE和標準Caché數字之間嘗試相等操作,並且對於標準Caché數字,返回的位數更大:

/// d ##class(PHA.TEST.Function).double4()
ClassMethod double4()
{
    SET x=$ZPI
    SET y=$DOUBLE($ZPI)
    IF x=y { 
        WRITE !,"Same" 
    } ELSE { 
        WRITE !,"Different"
        WRITE !,"standard:   ",x
        WRITE !,"IEEE float: ",y 
    }
}
DHC-APP>d ##class(PHA.TEST.Function).double4()
 
Different
standard:   3.141592653589793238
IEEE float: 3.1415926535897931159

下面的示例說明浮點數不一定等於相同值的數字字符串:


/// d ##class(PHA.TEST.Function).double5()
ClassMethod double5()
{
    SET x=123.4567891234560
    SET y=123.4567891234567
    IF x=$DOUBLE(x) { 
        WRITE !,"Same" 
    } ELSE { 
        WRITE !,"Different" 
    }
    IF y=$DOUBLE(y) { 
        WRITE !,"Same" 
    } ELSE { 
        WRITE !,"Different" 
    }
}
DHC-APP>d ##class(PHA.TEST.Function).double5()
 
Different
Different
/// d ##class(PHA.TEST.Function).double6()
ClassMethod double6()
{
    SET x=1234567891234560
    SET y=1234567891234567
    IF x=$DOUBLE(x) { 
        WRITE !,"Same" 
    } ELSE { 
        WRITE !,"Different" 
    }
    IF y=$DOUBLE(y) { 
        WRITE !,"Same" 
    } ELSE { 
        WRITE !,"Different" 
    }
}
DHC-APP>d ##class(PHA.TEST.Function).double6()
 
Same
Same
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章