第十三章 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
返回INF
和NAN
的一种方法是将相应的字符串指定为num输入值。这些输入字符串不区分大小写,并且可以带正负号(INF
解析符号,NAN
忽略符号)。要返回NAN
,请指定“NAN”,“ sNAN”,“ + NAN”,“-NAN”
。要返回INF
,请指定“ INF”,“ + INF”,“ Infinity”
。要返回-INF
,请指定“ -INF”,“ +-INF”
。
IEEEError
IEEEError控制$DOUBLE
如何响应无法解析的数字转换。如果IEEEError设置为0,则$DOUBLE
无法解析转换时将返回INF
和NAN
。如果IEEEError设置为1,则$DOUBLE
在无法解析转换时会生成标准的Caché错误代码。预设值为1。
可以使用%SYSTEM.Process类的IEEEError()
方法在每个进程的基础上控制此行为。可以通过设置Config.Miscellaneous
类的IEEEError属性来建立系统范围的默认行为。
返回 INF 与 NAN
当指定一个非常大的数字或指定一个不可解析的算术运算时,$DOUBLE
可以返回INF
和NAN
。仅当将IEEEError设置为返回INF
和NAN
时,才返回这些值。
不支持极大的浮点数。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 |
|
< 1.0E-323 |
0 |
0 |
1/$DOUBLE(0) |
INF |
|
1/$DOUBLE(–0) |
–INF |
|
$DOUBLE(1)/0 |
INF |
|
$DOUBLE(0)/0 |
NAN |
|
$ZLOG($DOUBLE(0)) |
–INF |
|
比较INF和NAN
可以将INF
视为数值进行比较。因此,INF = INF
,INF'= –INF
,–INF = –INF
,并且INF> –INF
。
不能将NAN
视为数值进行比较。因为不能使用数值运算符来有意义地比较NAN
(非数字),所以Caché运算(例如,等于,小于或大于)试图将$DOUBLE(“NAN”
)与另一个$DOUBLE(“NAN”)
进行比较。失败。与NAN <=
或> =
的比较是一种特殊情况。
$LISTSAME
确实认为$DOUBLE(“NAN”)
列表元素与另一个$DOUBLE(“NAN”)
列表元素相同。
NUMBER和$FNUMBER
这些ObjectScript函数支持$DOUBLE
数字。
$ISVALIDNUM
支持INF
和NAN
。尽管这些字符串不是数字,但是$ISVALIDNUM
对于这些值返回1,就像它们是数字一样。当用非数字字符串指定$DOUBLE
时,例如$DOUBLE(“”)
,Caché返回值0。因此,$ISVALIDNUM($DOUBLE(“”)))
返回1,因为0是一个数字。
$INUMBER
和$FNUMBER
提供支持$DOUBLE
值的“D”格式选项。$INUMBER
将数字转换为IEEE浮点数。$FNUMBER“D”
支持包括INF
和NAN
的大小写转换,以及选择$DOUBLE(-0)
应该返回0还是-0。
INF和NAN与操作符
可以对INF
和NAN
执行算术和逻辑运算。不建议将操作符与INF
和NAN
一起使用;如果执行了这样的操作,则结果如下:
算术运算符:
加法 | 减法 | 乘法 | 除法(/ 、\ 或# 运算符) |
---|---|---|---|
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 |
其他运算符(如模式匹配和串联)将NaN
和INF
视为三个字符的字母字符串。
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
、-INF
和NaN
值可以存储在JSON结构中,但不能由%ToJSON()
返回。尝试这样做会导致
错误,如下例所示:
/// d ##class(PHA.TEST.Function).double2()
ClassMethod double2()
{
SET jary=[123,($DOUBLE("INF"))] // executes successfully
WRITE jary.%ToJSON() // fails with 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