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

第四十四章 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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354