第二十三章 Caché 函数大全 $ISVALIDNUM 函数

第二十三章 Caché 函数大全 $ISVALIDNUM 函数

验证数值并返回布尔值;可选地提供范围检查。

大纲

$ISVALIDNUM(num,scale,min,max)

参数

  • num 要验证的数值。它可以是数值或字符串值、变量名或任何有效的ObjectScript表达式。
  • scale 可选-最小和最大范围比较的有效小数位数。
  • min 可选-允许的最小数值。
  • max 可选-允许的最大数值。

描述

num

要验证的数字可以是整数、实数或科学记数法数字(带有字母“E”“e”)。它可以是字符串、表达式或解析为数字的变量。它可以是有符号的,也可以是无符号的,并且可以包含前导零或尾随零。在以下情况下,验证失败($ISVALIDNUM返回0):

  • num是空字符串(“”)。
  • num包含数字0–9,前导+,小数点()和字母“E”“e”以外的任何字符。
  • num包含多个+符号,小数点或字母“E”“e”
  • 可选的+符号不是num的第一个字符。
  • 表示以10为底的指数的字母“E”“e”后跟数字字符串中的整数。

$ISVALIDNUM以外,在任何表达式中指定非整数指数的10进制数都会导致错误。例如,写7E3.5

Scale参数值使用数值的四舍五入或截断版本进行求值。$ISVALIDNUM处理不会更改num变量的实际值。

如果num是$DOUBLE返回的INF-INFNAN值,则$ISVALIDNUM返回1。

Caché支持的最大浮点数是1.7976931348623157081E308。在任何Caché数值运算中指定较大的数字都会产生错误。指定为$ISVALIDNUM支持的字符串的最大Caché十进制浮点数为9.223372036854775807E145。对于大于此长度的浮点数字符串,请使用$ISVALIDDOUBLE

scale

Scale参数在范围检查期间用于指定要比较的小数位数。为比例尺指定整数值;将忽略比例尺值中的小数位。可以指定大于其他参数中指定的小数位数的比例值。可以将比例值指定为-1;所有其他负的比例值都会导致<function>错误。

非负范围值会导致在执行最小和最大范围检查之前将num舍入为该小数位数。刻度值为0会导致在执行范围检查之前将num舍入为整数值(3.9=4)。刻度值为-1会导致在执行范围检查之前将num截断为整数值(3.9=3)。要比较所有指定的数字而不舍入或截断,请省略Scale参数。非数字或空字符串的比例值等效于比例值0。

对除-1以外的所有比例值执行舍入。值为5或更大时始终向上舍入。

如果省略Scale参数,请保留逗号作为占位符。

舍入数字时,请注意IEEE浮点数和Caché小数的精度不同。$DOUBLE IEEE浮点数使用二进制表示法进行编码。它们的精度为53个二进制位,相当于15.95个十进制数字的精度。(请注意,二进制表示法并不完全对应于十进制分数。)。由于大多数小数不能用此二进制记数法精确表示,因此IEEE浮点数可能与相应的Caché浮点数略有不同。在所有支持的Caché系统平台上,Caché小数的精度为18位小数。当IEEE浮点数显示为小数时,二进制位通常被转换为具有远远多于18个十进制位的小数。这并不意味着IEEE浮点数比,Caché小数更精确。

min and max

可以指定最小允许值、最大允许值、两者都不指定或两者都指定。如果指定,则Num值(在缩放操作之后)必须大于或等于最小值,且小于或等于最大值。作为最小或最大值的空字符串等于零。如果值不满足这些条件,$ISVALIDNUM将返回0。

如果省略参数,请保留逗号作为占位符。例如,当省略SCALE而指定MIN或MAX时,或者省略MIN并指定MAX时。尾随逗号将被忽略。

如果NUM、MIN或MAX值是$DOUBLE数字,则对于此范围检查,所有这三个数字都被视为$DOUBLE数字。这可以防止$DOUBLE数的小的生成小数部分导致意外的范围错误。

示例

在以下示例中,每次调用$ISVALIDNUM都返回1(有效数字):

/// d ##class(PHA.TEST.Function).ISVALIDNUM()
ClassMethod ISVALIDNUM()
{
    WRITE !,$ISVALIDNUM(0)        ; 所有整数 OK
    WRITE !,$ISVALIDNUM(4.567)    ; 小数 OK
    WRITE !,$ISVALIDNUM("4.567")  ; 数字字符 OK
    WRITE !,$ISVALIDNUM(-.0)      ; 符号数字 OK
    WRITE !,$ISVALIDNUM(+004.500) ; 前导或尾随0 OK
    WRITE !,$ISVALIDNUM(4E2)      ; 科学计数 OK
}

DHC-APP>d ##class(PHA.TEST.Function).ISVALIDNUM()
 
1
1
1
1
1
1

在以下示例中,每次调用$ISVALIDNUM都返回0(无效数字):

/// d ##class(PHA.TEST.Function).ISVALIDNUM1()
ClassMethod ISVALIDNUM1()
{
    WRITE !,$ISVALIDNUM("")      ; 空字符串无效
    WRITE !,$ISVALIDNUM("4,567") ; 逗号不允许
    WRITE !,$ISVALIDNUM("4A")    ; 无效字符
}
DHC-APP>d ##class(PHA.TEST.Function).ISVALIDNUM1()
 
0
0
0

在下面的示例中,每次调用$ISVALIDNUM都返回1(有效数字),即使INF(无穷大)和NaN(不是A数字)严格地说不是数字:

/// d ##class(PHA.TEST.Function).ISVALIDNUM2()
ClassMethod ISVALIDNUM2()
{
    DO ##class(%SYSTEM.Process).IEEEError(0)
    WRITE !,$ISVALIDNUM($DOUBLE($ZPI))  ; DOUBLE numbers OK
    WRITE !,$ISVALIDNUM($DOUBLE("INF")) ; DOUBLE INF OK
    WRITE !,$ISVALIDNUM($DOUBLE("NAN")) ; DOUBLE NAN OK
    WRITE !,$ISVALIDNUM($DOUBLE(1)/0)   ; generated INF OK
}

DHC-APP> d ##class(PHA.TEST.Function).ISVALIDNUM2()
 
1
1
1
1

以下示例显示了min和max参数的使用。以下所有返回1(数字有效,也通过范围检查):

/// d ##class(PHA.TEST.Function).ISVALIDNUM3()
ClassMethod ISVALIDNUM3()
{
    WRITE !,$ISVALIDNUM(4,,3,5)    ; scale 可以忽略
    WRITE !,$ISVALIDNUM(4,2,3,5)   ; scale 可以大于整数位数
    WRITE !,$ISVALIDNUM(4,0,,5)    ; 最大最小值可以忽略
    WRITE !,$ISVALIDNUM(4,0,4,4)   ; 包含最大最小值
    WRITE !,$ISVALIDNUM(-4,0,-5,5) ; 负数
    WRITE !,$ISVALIDNUM(4.00,2,04,05) ; 前导或尾随0 
    WRITE !,$ISVALIDNUM(.4E3,0,3E2,400) ; 以10为底的指数扩展
}
DHC-APP>d ##class(PHA.TEST.Function).ISVALIDNUM3()
 
1
1
1
1
1
1
1

下面的示例显示了Scale参数与min和max的使用。以下所有返回1(数字有效,也通过范围检查):

/// d ##class(PHA.TEST.Function).ISVALIDNUM4()
ClassMethod ISVALIDNUM4()
{
   WRITE !,$ISVALIDNUM(4.55,,4.54,4.551)
     ; 省略小数位时,将检查num的所有数字。
   WRITE !,$ISVALIDNUM(4.1,0,4,4.01)
     ; 当scale = 0时,num在最小值和最大值检查之前四舍五入为整数值(0个小数位)。
   WRITE !,$ISVALIDNUM(3.85,1,3.9,5)
     ; Num四舍五入为1个小数位数(值向上舍入为5或更大);在进行最小检查之前。
   WRITE !,$ISVALIDNUM(4.01,17,3,5) 
     ; 小数位数可以大于数字位数。
   WRITE !,$ISVALIDNUM(3.9,-1,2,3)
     ; 当scale = -1时,num被截断为整数值
}
DHC-APP>d ##class(PHA.TEST.Function).ISVALIDNUM4()
 
1
1
1
1
1

注意

$ISVALIDDOUBLE$ISVALIDNUM比较

$ISVALIDDOUBLE$ISVALIDNUM函数都验证美国格式的数字并返回布尔值(0或1)。

  • 这两个函数都接受$DOUBLE返回的INF-INFNaN值作为有效数字。$ISVALIDDOUBLE还接受不区分大小写的字符串“NaN”“INF”、变体“Infinity”“snan”以及任何以单个加号或减号开头的字符串作为有效数字。$ISVALIDNUM以无效为由拒绝所有这些字符串,并返回0。
/// d ##class(PHA.TEST.Function).ISVALIDDOUBLE6()
ClassMethod ISVALIDDOUBLE6()
{
    WRITE !,$ISVALIDNUM($DOUBLE("NAN"))    ; returns 1
    WRITE !,$ISVALIDDOUBLE($DOUBLE("NAN")) ; returns 1
    WRITE !,$ISVALIDNUM("NAN")             ; returns 0
    WRITE !,$ISVALIDDOUBLE("NAN")          ; returns 1
}
  • 这两个函数都解析有符号和无符号整数(包括-0)、科学记数法数字(带有“E”“e”)、实数(123.45)和数字字符串(“123.45”)。将所有这些字符串视为无效,并返回0。
  • 这两个函数都不识别欧洲小数分隔符字符(逗号())或NumericGroupSeparator字符(美式格式:逗号();欧式格式:句点(.))。例如,无论当前的区域设置如何,两者都会将字符串“123,456”作为无效数字拒绝。
  • 这两个函数都解析数字的多个前导符号(+-)。两者都不接受带引号的数字字符串中的多个前导符号。

如果数字字符串太大,无法用Caché 浮点数表示,则默认情况下会自动将其转换为IEEE双精度数字。但是,如此大的数字无法通过$ISVALIDNUM测试,如以下示例所示:

/// d ##class(PHA.TEST.Function).ISVALIDNUM5()
ClassMethod ISVALIDNUM5()
{
    WRITE !,"E127不需要IEEE转换"
    WRITE !,$ISVALIDNUM("9223372036854775807E127")
    WRITE !,$ISVALIDDOUBLE("9223372036854775807E127")
    WRITE !,"E128自动IEEE转换"
    WRITE !,$ISVALIDNUM("9223372036854775807E128")
    WRITE !,$ISVALIDDOUBLE("9223372036854775807E128")
}

$ISVALIDNUM$NORMALIZE$NUMBER比较

$ISVALIDNUM$NORMALIZE$NUMBER函数都验证数字。$ISVALIDNUM返回布尔值(0或1)。$NORMALIZE$NUMBER返回指定数字的验证版本。

DHC-APP>w $number("1.1",0)
1
DHC-APP>w $number("1.5",0)
2
DHC-APP>w $number("1.5",-1)
0

这三个函数提供不同的验证标准。选择最符合需要的。

  • 美式格式号码通过所有三个函数进行验证。欧洲格式的数字仅由$NUMBER函数验证。
  • 这三个函数都解析有符号和无符号整数(包括-0)、科学记数法数字(带有“E”“e”)以及带小数部分的数字。但是,可以(使用“i”格式)将$number设置为拒绝带有小数部分的数字(包括具有负基10指数的科学记数法)。这三个函数同时解析数字(123.45)和数字字符串(“123.45”)。
  • 所有三个函数都会去掉前导零和尾随零。除非后面跟一个非零值,否则会去掉小数字符。
  • DecimalSeparator$number验证小数字符(美国格式:句点(.)。或欧洲格式:逗号())基于其格式参数(或当前区域设置的默认值)。其他函数只验证美式格式的十进制数字,而不考虑当前的区域设置。
  • NumericGroupSeparator$Number接受NumericGroupSeparator字符(美式格式:逗号()或空格;欧式格式:句点(.)。或空格)。它接受并剥离任意数量的NumericGroupSeparator字符,而与位置无关。例如,在美国格式中,它将“12 3,,4,56.9,9”验证为数字123456.99$Normalize不识别NumericGroupSeparator字符。它逐个字符进行验证,直到遇到非数字字符;例如,它将“123,456.99”验证为数字123$ISVALIDNUM将字符串“123,456”作为无效数字拒绝。
  • 数字的所有三个函数都解释多个前导符号(+-)。但是,只有$Normalize接受带引号的数字字符串中的多个前导符号。
  • 尾随+-符号:这三个函数都拒绝数字中的尾随符号。但是,在带引号的数字字符串$NUMBER中,$NORMALIZE解析一个(且只有一个)尾随符号,$NORMALIZE解析多个尾随符号,$ISVALIDNUM拒绝任何包含尾随符号的字符串作为无效数字。
  • 括号:$number将带引号的字符串中无符号数字周围的括号解析为负数。$Normalize$ISVALIDNUM拒绝括号。
  • 包含多个小数字符的数字字符串:$NORMALIZE逐个字符进行验证,直到遇到第二个小数字符。例如,在美国格式中,它将“123.4.56”验证为数字123.4$NUMBER$ISVALIDNUM拒绝任何包含一个以上小数字符的字符串作为无效数字。

包含其他非数字字符的数字字符串:$Normize逐个字符进行验证,直到遇到字母字符。它确认“123A456”为数字123$NUMBER$ISVALIDNUM验证整个字符串,它们将“123A456”作为无效数字拒绝。

  • 空字符串:$Normalize将空字符串解析为零(0)。$NUMBER$ISVALIDNUM拒绝空字符串。

$ISVALIDNUM$NUMBER函数提供可选的最小/最大范围检查。

$ISVALIDNUM$NORMALIZE$NUMBER都提供将数字舍入到指定的小数位数。$ISVALIDNUM$NORMALIZE可以对小数位进行舍入,并对带有小数部分的数字进行舍入或截断以返回整数。例如,$NORMALIZE可以将488.65舍入到488.7489,也可以将其截断为488$number既可以舍入小数位,也可以舍入整数位。例如,$NUMBER可以取整为488.65488.7

DHC-APP>w $number(488.65)
488.65
DHC-APP>w $number(488.65,1)
488.7
DHC-APP>w $number(488.65,0)
489
DHC-APP>w $NORMALIZE(488.65,0)
489
DHC-APP>w $NORMALIZE(488.65,1)
488.7
DHC-APP>w $NORMALIZE(488.65,3)
488.65
DHC-APP>w $NORMALIZE(488.65,-1)
488

$NORMALIZE 可以直接取整,$number可以四舍五入 ,二者都可以返回数字。

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