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

tech2022-09-07  107

文章目录

第十三章 Caché 函数大全 $DOUBLE 函数 大纲参数 描述均等比较和混合算法整数除法平台独立性 INF 与 NANINF和NAN作为输入值IEEEError返回 INF 与 NAN比较INF和NAN I S V A L I D E N U M , ISVALIDENUM, ISVALIDENUMNUMBER和$FNUMBERINF和NAN与操作符INF and 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返回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=0IEEEError=1> 1.0E308INF<MAXNUMBER>< 1.0E-323001/$DOUBLE(0)INF<DIVIDE>1/$DOUBLE(–0)–INF<DIVIDE>$DOUBLE(1)/0INF<DIVIDE>$DOUBLE(0)/0NAN<ILLEGAL VALUE>$ZLOG($DOUBLE(0))–INF<DIVIDE>

比较INF和NAN

可以将INF视为数值进行比较。因此,INF = INF,INF'= –INF,–INF = –INF,并且INF> –INF。

不能将NAN视为数值进行比较。因为不能使用数值运算符来有意义地比较NAN(非数字),所以Caché运算(例如,等于,小于或大于)试图将$DOUBLE(“NAN”)与另一个$DOUBLE(“NAN”)进行比较。失败。与NAN <=或> =的比较是一种特殊情况。

$LISTSAME确实认为$DOUBLE(“NAN”)列表元素与另一个$DOUBLE(“NAN”)列表元素相同。

I S V A L I D E N U M , ISVALIDENUM, ISVALIDENUMNUMBER和$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=NANNAN-NAN=NANNAN*NAN=NANNAN/NAN=NANNAN+INF=NANNAN-INF=NANNAN*INF=NANNAN/INF=NAN 无|`INF-NAN=NAN`| 无 |`INF/NAN=NAN`

INF+INF=INF| INF-INF=NAN| INF*INF=INF |INF/INF=NAN

逻辑运算符:

等于(=)NANINFNAN00INF01 小于 (<) 或大于 (>)NANINFNAN00INF00

其他运算符(如模式匹配和串联)将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()返回。尝试这样做会导致<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
最新回复(0)