第十二章 Caché 函数大全 $DECIMAL 函数
返回转换为Caché浮点值的数字。
大纲
$DECIMAL(num,digits)
参数
- num 要转换的数值。通常,这是一个IEEE浮点数。
- digits 可选—一个整数,指定要返回的有效位数。
$DECIMAL
使用IEEE浮点舍入算法将返回值舍入到该位数。有效值为1到38,以及0。如果digits大于位数,则该值将保持不变。如果digits为0,则对num不进行舍入,除非有效位数超过20个。
描述
$DECIMA
L返回转换为Caché十进制浮点数据类型的浮点数。此函数用于将IEEE双精度(64位)二进制浮点格式的小数转换为Caché十进制浮点格式的相应小数。这与$DOUBLE
函数执行的操作相反。
CachéSQL数据类型DOUBLE和DOUBLE PRECISION表示IEEE浮点数; FLOAT数据类型表示标准Caché小数。
IEEE浮点数在内部使用53个二进制位表示。由于大多数小数十进制数字都没有精确的二进制表示形式,因此$DOUBLE
格式的小数通常与$DECIMAL
转换略有不同。在所有受支持的Caché系统平台上,标准Caché小数部分的精度约为18.96个十进制数字。当IEEE浮点数显示为小数时,二进制位通常会转换为具有远远超过18个十进制数字的小数。这并不意味着IEEE浮点数比标准Caché小数更精确。
num值可以指定为数字或数字字符串。在$DECIMAL
转换之前,它将解析为规范形式(删除了前导零和尾随零,解决了多个正负号等)。如果num值超出可以转换为FLOAT数据类型的值范围,则$DECIMAL
会生成<MAXNUMBER>
错误。为num指定非数字字符串将返回0。为num指定混合数字字符串(例如“7dwarves”
或“ 7.5.4”
)会截断第一个非数字字符的输入值,然后转换数字部分。
默认四舍五入如下:
- 小数部分:如果未指定数字,并且num具有19个以上有效数字,则
$DECIMAL
将小数部分四舍五入,以使结果数字为19位数字(如果四舍五入后跟零,则为更少)。$DECIMAL
始终四舍五入为具有较大绝对值的最接近的小数。 - 非常大的整数:如果未指定数字,并且num在小数点左边有超过19个有效整数,则
$DECIMAL
会四舍五入,以使所得整数具有19个有效数字,其余整数用零表示。 - 小于1的非常小的分数数字:如果未指定digits,并且num是在有效值前的小数点右边的小数点右边有19个零以上的小数,
$DECIMAL
将保留零,然后四舍五入,以便将有效位的小数部分四舍五入。小数舍入为19位有效数字。 - 具有非常小的分数数字的整数:如果未指定数字,并且num是一个数字,则该数字包含一个非零整数部分,在有效值前小数点右边有19个零以上,
$DECIMAL
会四舍五入为整数。
digits参数可用于将返回值四舍五入到指定的位数。尾随零始终被删除。如果数字是一个正整数,则使用IEEE舍入标准进行舍入。如果num具有38个以上的有效数字(且数字=38),则$DECIMAL
将数字的小数部分四舍五入到第38个数字,并用零表示接下来的所有num数字。如果数字大于38,则会生成<ILLEGAL VALUE>
错误。
如果digits为0,则数字强制转换为字符串排序规则;否则为0。相当于(+ num)_“”
。如果num为20位以下,则digits = 0与digits = 20相同。
但是,如果数字为0且num大于20个数字,则执行特殊舍入(不是IEEE舍入),如下所示。进行四舍五入以返回20位数字。如果第20位四舍五入为0或5,则对第20位进行特殊舍入。如果第20位四舍五入为0或5,则Caché分别将其舍入为9或4。如果第20位数字向下舍入为0或5,则Caché分别将其向上舍入为1或6。其他20位数字值则保持不变。该舍入算法用于提供正确的数字排序规则,并避免舍入不一致。
整数除法
对于某些值,Caché十进制浮点数和IEEE双精度数会产生不同的整数除积。例如:
DHC-APP>WRITE !,"Cache \: ",$DECIMAL(4.1)\.01
Cache \: 410
DHC-APP>WRITE !,"Double \: ",$DOUBLE(4.1)\.01
Double \: 409
INF 与 NAN
如果num是INF
,则会生成<MAXNUMBER>
错误。如果num是NAN
,则会生成 <ILLEGAL VALUE>
错误。这些无效值显示在以下示例中:
DHC-APP>SET i=$DOUBLE("INF")
DHC-APP>SET n=$DOUBLE("NAN")
DHC-APP>WRITE $DECIMAL(i)
WRITE $DECIMAL(i)
^
<MAXNUMBER>
DHC-APP>WRITE $DECIMAL(n)
WRITE $DECIMAL(n)
^
<ILLEGAL VALUE>
示例
以下示例说明,将$DECIMAL
应用于已经采用Caché格式的小数时无效:
/// d ##class(PHA.TEST.Function).decimal()
ClassMethod decimal()
{
SET x=$DECIMAL($ZPI)
SET y=$ZPI
IF x=y {
WRITE !,"相同:"
WRITE !,"Cache $DECIMAL: ",x
WRITE !,"Native Cache: ",y
} ELSE {
WRITE !,"不同:"
WRITE !,"Cache $DECIMAL: ",x
WRITE !,"Native Cache: ",y
}
}
以下示例将pi的值作为$DOUBLE
值和标准Caché数值返回。此示例表明,不应在$DOUBLE
和标准Caché编号之间尝试相等操作,并且不能通过使用$DECIMAL
将IEEE转换回Caché来恢复等效性:
/// d ##class(PHA.TEST.Function).decimal1()
ClassMethod decimal1()
{
SET x=$DECIMAL($ZPI)
SET y=$DOUBLE($ZPI)
SET z=$DECIMAL(y)
IF x=y {
WRITE !,"Cache & IEEE Same"
} ELSEIF x=z {
WRITE !,"Cache & IEEE-to-Cache same"
} ELSE {
WRITE !,"三者不同"
WRITE !,"Cache decimal: ",x
WRITE !,"IEEE float: ",y
WRITE !,"IEEE to Cache: ",z
}
}
DHC-APP>d ##class(PHA.TEST.Function).decimal1()
三者不同
Cache decimal: 3.141592653589793238
IEEE float: 3.1415926535897931159
IEEE to Cache: 3.141592653589793116
以下示例将pi的$DECIMAL
转换返回为$DOUBLE
值。这些转换通过不同的数字参数值取整:
/// d ##class(PHA.TEST.Function).decimal2()
ClassMethod decimal2()
{
SET x=$DOUBLE($ZPI)
WRITE !,$DECIMAL(x)
/* returns 3.141592653589793116 (19 digits) */
WRITE !,$DECIMAL(x,1)
/* returns 3 */
WRITE !,$DECIMAL(x,8)
/* returns 3.1415927 (note rounding) */
WRITE !,$DECIMAL(x,12)
/* returns 3.14159265359 (note rounding) */
WRITE !,$DECIMAL(x,18)
/* returns 3.14159265358979312 */
WRITE !,$DECIMAL(x,19)
/* returns 3.141592653589793116 (19 digits) */
WRITE !,$DECIMAL(x,20)
/* returns 3.141592653589793116 (19 digits) */
WRITE !,$DECIMAL(x,21)
/* returns 3.141592653589793116 (19 digits) */
WRITE !,$DECIMAL(x,0)
/* returns 3.1415926535897931159 (20 digits) */
}
DHC-APP>d ##class(PHA.TEST.Function).decimal2()
3.141592653589793116
3
3.1415927
3.14159265359
3.14159265358979312
3.141592653589793116
3.141592653589793116
3.141592653589793116
3.1415926535897931159
网友评论