第四十四章 Caché 函数大全 $NORMALIZE 函数
验证并返回一个数值;舍入到指定的精度。
大纲
$NORMALIZE(num,scale)
参数
- num 要验证的数值。它可以是数值或字符串值、变量名或任何有效的对象脚本表达式。
- scale 将num四舍五入为返回值的有效位数。该数字可以大于或小于num中小数位数的实际数量。允许的值为0(四舍五入为整数)、–1(截断为整数)和正整数(四舍五入为指定的小数位数)。没有最大刻度值。但是,函数最大值不能超过数值精度。对于标准Caché小数,函数比例最大值为18(减去整数位数–1)。
描述
$NORMALIZE
函数验证num并返回num的规范化形式。它使用比例参数对小数位数进行舍入(或截断)。可以使用scale参数将实数舍入为指定的小数位数,将实数舍入为整数,或将实数截断为整数。
舍入后,$NORMALIZE
从返回值中移除尾随零。因此,返回的小数位数可能小于小数位数,如下例所示:
/// d ##class(PHA.TEST.Function).NORMALIZE()
ClassMethod NORMALIZE()
{
WRITE $NORMALIZE($ZPI,11),!
WRITE $NORMALIZE($ZPI,12),! /* 去掉尾随0 */
WRITE $NORMALIZE($ZPI,13),!
WRITE $NORMALIZE($ZPI,14)
}
DHC-APP>d ##class(PHA.TEST.Function).NORMALIZE()
3.14159265359
3.14159265359
3.1415926535898
3.14159265358979
参数
num
要验证的数字可以是整数、实数或科学记数法数字(带有字母“E”
或“e”
)。它可以是解析为数字的字符串、表达式或变量。它可以是有符号的或无符号的,并且可以包含前导零或尾随零。$NORMALIZE
逐字符验证。如果出现以下情况,它将停止验证并返回字符串的已验证部分:
- num包含除数字0–9、+或–号、小数点(。),还有一个字母
“E”
或者“E”
。 - 数字包含一个以上的小数点,或字母
“E”
或“E”
。 - 如果在num中的一个数字后发现一个
+
或–
符号,它将被认为是一个尾随符号,并且不再解析其他数字。 - 字母
“E”
或“E”
后面没有整数。
scale 参数值导致返回值是num值的舍入或截断版本。$NORMALIZE
处理不会更改num变量的实际值。
scale
强制小数位数参数用于指定舍入到多少小数位数。根据指定的值,比例对小数位数、舍入到指定的小数位数、舍入到整数或截断到整数没有影响。
非负刻度值导致num被舍入到小数位数。舍入时,总是向上舍入5或更大的值。为避免四舍五入,请使小数位数大于num中可能的小数位数。标度值为0会导致num被舍入为整数值(3.9 = 4
)。标度值–1会导致num被截断为整数值(3.9 = 3
)。非数字或空字符串的比例值相当于0的比例值。
为比例指定一个整数值;忽略刻度值中的十进制数字。您可以指定一个大于num中指定的小数位数的小数位数。可以指定–1的比例值;所有其他负刻度值都会导致<FUNCTION>
错误。
示例
在以下示例中,每次调用$NORMALIZE
都会返回num的规范化版本,并带有指定的舍入(或整数截断):
/// d ##class(PHA.TEST.Function).NORMALIZE1()
ClassMethod NORMALIZE1()
{
WRITE !,$NORMALIZE(0,0) ; All integers OK
WRITE !,$NORMALIZE("",0) ; Null string is parsed as 0
WRITE !,$NORMALIZE(4.567,2) ; Real numbers OK
WRITE !,$NORMALIZE("4.567",2) ; Numeric strings OK
WRITE !,$NORMALIZE(-+.0,99) ; Leading/trailing signs OK
WRITE !,$NORMALIZE(+004.500,1) ; Leading/trailing 0's OK
WRITE !,$NORMALIZE(4E2,-1) ; Scientific notation OK
}
DHC-APP>d ##class(PHA.TEST.Function).NORMALIZE1()
0
0
4.57
4.57
0
4.5
400
在以下示例中,每次调用$NORMALIZE
都会返回num的数字子集:
/// d ##class(PHA.TEST.Function).NORMALIZE2()
ClassMethod NORMALIZE2()
{
WRITE !,$NORMALIZE("4,567",0)
; 无法识别NumericGroupSeparators(逗号)
; 在此处,验证停止在逗号处,并返回4。
WRITE !,$NORMALIZE("4A",0)
; 无效(非数字)字符暂停验证
}
DHC-APP>d ##class(PHA.TEST.Function).NORMALIZE2()
4
4
以下示例显示了使用scale参数来舍入(或截断)返回值:
/// d ##class(PHA.TEST.Function).NORMALIZE3()
ClassMethod NORMALIZE3()
{
WRITE !,$NORMALIZE(4.55,2)
; 当scale等于num的小数位数时,将返回num的所有数字而不进行舍入。
WRITE !,$NORMALIZE(3.85,1)
; num被四舍五入为1个小数位,(四舍五入为5或更大的值),这里返回3.9。
WRITE !,$NORMALIZE(4.01,17)
; 小数位数可以大于小数位数,并且不进行舍入;这里返回4.01。
WRITE !,$NORMALIZE(3.85,0)
; 当scale = 0时,num被舍入为整数值。这里返回4。
WRITE !,$NORMALIZE(3.85,-1)
; 当scale = -1时,num被截断为整数值。这里返回3。
}
DHC-APP>d ##class(PHA.TEST.Function).NORMALIZE3()
4.55
3.9
4.01
4
3
注意
$DOUBLE
数字
$DOUBLE
IEEE浮点数使用二进制表示法编码。大多数十进制小数不能用此二进制表示法精确表示。当使用刻度值将$DOUBLE
值输入到$NORMALIZE
时,返回值包含的小数位数通常多于刻度中指定的位数,因为分数小数结果不能用二进制表示,因此返回值必须四舍五入到最接近的可表示$DOUBLE
值,如以下示例所示:
/// d ##class(PHA.TEST.Function).NORMALIZE4()
ClassMethod NORMALIZE4()
{
SET x=1234.1234
SET y=$DOUBLE(1234.1234)
WRITE "Decimal: ",$NORMALIZE(x,2),!
WRITE "Double: ",$NORMALIZE(y,2),!
WRITE "Dec/Dub: ",$NORMALIZE($DECIMAL(y),2)
}
DHC-APP>d ##class(PHA.TEST.Function).NORMALIZE4()
Decimal: 1234.12
Double: 1234.1199999999998908
Dec/Dub: 1234.12
如果要标准化$DOUBLE
值以进行十进制格式化,则应在标准化结果之前将$DOUBLE
值转换为十进制表示形式,如上面的示例所示。
$NORMALIZE
处理$DOUBLE(“INF”)
和$DOUBLE(“NAN”)
值,并返回INF
和NAN
。
忽略DecimalSeparator值
$NORMALIZE
旨在对数字进行运算。 num字符串被解释为数字。 Caché在将数字提供给$NORMALIZE
之前将其转换为规范形式。转换为规范数字不会将DecimalSeparator属性值用于当前语言环境。
例如,如果为num指定字符串“00123.4500”
,则$NORMALIZE
会将其视为规范数字123.45
,而不考虑当前的DecimalSeparator值。如果指定字符串“00123,4500”
,则无论当前的DecimalSeparator值如何,$NORMALIZE
都将其视为规范数字123
(在第一个非数字字符处截断)。
如果要使用将字符串作为输入的函数,请使用$INUMBER
。如果要使用产生字符串结果的函数,请使用$FNUMBER
。
$NORMALIZE
和$NUMBER
比较
$NORMALIZE
和$NUMBER
函数均验证数字并返回指定数字的经过验证的版本。
这两个功能提供了不同的验证标准。选择最能满足需求的产品。
- 这两个函数都解析有符号和无符号整数(包括–0),科学计数法数字(带有
“E”
或“e”
)和实数。但是,可以设置$NUMBER
(使用“I”
格式)以拒绝带有小数部分的数字(包括以10为底的指数表示的科学计数法)。这两个函数都解析数字(123.45
)和数字字符串(“123.45”
)。 - 这两个函数都去除前导零和尾随零。除非后面加上非零值,否则将除去小数字符。
- 包含NumericGroupSeparator:
$NUMBER
的数字字符串将解析NumericGroupSeparator字符(美国格式:逗号(,
);欧洲格式:句点(。
)或撇号('
))和十进制字符(美国格式:句点(。
)或欧洲格式:逗号(,
))为其格式参数(或当前语言环境的默认值)。它接受并剥离任意数量的NumericGroupSeparator字符。例如,以美国格式,它将“123,,4,56.99”
验证为数字123456.99
。$NORMALIZE
无法识别NumericGroupSeparator字符。它逐个字符地验证,直到遇到非数字字符为止。例如,它将“123,456.99”
验证为数字123
。 - 这两个功能都为数字解释了多个前导符号(
+
和–
)。只有$NORMALIZE
接受带引号的数字字符串中的多个前导符号。 - 尾随
+
和–
符号:两个函数均拒绝数字尾随符号。在带引号的数字字符串中,$NUMBER
解析一个(并且只有一个)尾随符号。$NORMALIZE
解析多个尾随符号。 - 括号:
$NUMBER
将括号内的无符号数字括起来的括号解析为负数。$NORMALIZE
将括号视为非数字字符。 - 包含多个十进制字符的数字字符串:
$NORMALIZE
逐字符验证直到遇到第二个十进制字符。例如,以美国格式,它将“123.4.56”
验证为数字123.4
。$NUMBER
拒绝包含多于一个十进制字符的任何字符串作为无效数字。 - 包含其他非数字字符的数字字符串:
$NORMALIZE
逐字符验证直到遇到字母字符。它将“123A456”
验证为数字123
。$NUMBER
验证或拒绝整个字符串;它拒绝“123A456”
为无效号码。 - 空字符串:
$NORMALIZE
将空字符串解析为零(0)。$NUMBER
拒绝空字符串。
DHC-APP>w $number(1)
1
DHC-APP>w $number("1")
1
DHC-APP>w $number("1.2")
1.2
DHC-APP>w $number("1.2.3")
DHC-APP>w $number("(1.2.3)")
DHC-APP>w $number("(1.2)")
-1.2
$NUMBER
功能提供可选的最小/最大范围检查。也可以使用$ISVALIDNUM
函数。
$NORMALIZE
,$NUMBER
和$ISVALIDNUM
都可以将数字舍入为指定的小数位数。 $NORMALIZE
可以舍入小数位数,并舍入或截断实数以返回整数。例如,$NORMALIZE
可以将488.65
舍入为488.7
或489
,或者将其截断为488
。$NUMBER
可以舍入实数或整数。例如,$NUMBER
可以将488.65
舍入为488.7
、489
、490
或500
。
DHC-APP>w $number(488.65,1)
488.7
DHC-APP>w $number(488.65,2)
488.65
DHC-APP>w $number(488.65,3)
488.65
DHC-APP>w $number(488.65,-1)
490
DHC-APP>w $number(488.65,-2)
500