美文网首页
第十三章 Caché 函数大全 $DOUBLE 函数

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

作者: Cache技术分享 | 来源:发表于2020-09-03 07:50 被阅读0次

    第十三章 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
    

    相关文章

      网友评论

          本文标题:第十三章 Caché 函数大全 $DOUBLE 函数

          本文链接:https://www.haomeiwen.com/subject/uufnsktx.html