zl程序教程

您现在的位置是:首页 >  其它

当前栏目

第四十四章 Caché 函数大全 $NORMALIZE 函数

函数 大全 Cach
2023-09-11 14:15:37 时间

第四十四章 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”)值,并返回INFNAN

忽略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.7489,或者将其截断为488$NUMBER可以舍入实数或整数。例如,$NUMBER可以将488.65舍入为488.7489490500

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