第二章 Caché 函数大全 $BIT 函数

第二章 Caché 函数大全 $BIT 函数

返回和或设置位串中指定位置的位值。

大纲

$BIT(bitstring,position)

SET $BIT(bitstring,position) = value

参数

  • bitstring
    • 计算结果为位串的表达式。
    • 对于$BIT,位串可以是解析为位串的任何表达式,包括任何类型的变量,$FACTOR,用户定义的函数或oref.prop.. propi%prop属性引用。
    • 对于SET $BIT,位串可以是任何类型的变量,包括i%Prop()属性实例变量。
  • position 位串中的位位置。计算为正整数的文字或表达式。位位置从1开始计数。
  • value 在位置设置的位值。计算为整数0或1的文字或表达式。

描述

$BIT用于从压缩的位串返回位值。$BIT(bitstring,position)返回给定位串表达式bitstring中指定位置position的位值(0或1)。如果没有为某个位置定义值,则$BIT将为该位置返回0。位置从1开始计数;如果position小于1(0或负数)或大于位串的长度,则函数返回0。

如果位串是未定义的变量或空串(“”),则$BIT函数将返回0。如果位串不是有效的位串值,则会发生<INVALID BIT STRING>错误。

SET $BIT

SET $BIT用于设置位串压缩位串中的指定位值如果未定义位串,则SET $ BIT将位串变量定义为压缩位串并设置指定的位值。

SET $ BIT(bitstring,position)= value对由bitstring指定的位串执行原子位设置。如果值为1,则位置位置的位设置为1。如果值为0,则清除该位(设置为0)。仅应使用0或1的整数; Caché会将任何非数字值(例如“ true”或“ false”)转换为0。

位的位置从1开始计数。如果位串短于指定位置,则Caché将0位填充到指定位置。如果将位置指定为0,则Caché会生成<VALUE OUT OF RANGE>错误。

位串变量必须是未定义的变量,已经设置为位串值的变量或设置为空字符串(“”)的变量。尝试对已设置为非位字符串值的变量使用SET $BIT会导致<INVALID BIT STRING>错误。

SET $BIT位字符串参数不支持oref.property..属性语法。

SET $BIT位字符串参数支持本地(非继承)属性和从超类继承的属性的i%property语法。如果尝试在现有代码中设置继承的属性会生成<FUNCTION>错误,则重新编译该例程应可以解决此错误并允许设置继承的属性。

显示位串

如示例中所示,可以使用WRITE将位串中单个位的内容显示为$BIT的返回值。

Caché有几个命令来显示变量的内容。但是,由于$BIT位字符串是压缩的二进制字符串,因此WRITE不会显示有用的值。ZZDUMP显示压缩的二进制字符串的十六进制表示形式,对于大多数用途而言,这也不是一个有用的值。

ZWRITEZZWRITE$ZWCHAR($zwc)两字节(宽)字符显示压缩二进制字符串的十进制表示形式。但是,它们还会显示注释,该注释以从左到右的顺序列出未压缩的“1”位,并以逗号分隔。如果有三个或更多连续的“1”位,它将使用两个点语法(n..m)将它们列出为一个范围(含)。例如,位串[1,0,1,1,1,1,0,1]显示为/*$bit(1,3..6,8)*/。位字符串[1,1,1,1,1,1,1,1]显示为/*$bit(1..8)*/。位字符串[0,0,0,0,0,0,0,0]显示为/ * $ bit()* /

$DATA对于压缩的二进制字符串变量返回1,其中包括全零的位字符串,例如[0,0,0,0,0,0,0,0,0]$GET返回空字符串作为压缩的二进制字符串,而不管其值如何;$GET还返回未定义变量的空字符串。

示例

请注意,在以下示例中,未设置的位始终为0。
下面的示例使用SET $BIT创建一个压缩的位串。然后,它反复调用$BIT以显示位串中的位:

/// d ##class(PHA.TEST.Function).BIT()
ClassMethod BIT()
{
    
    
	SET $BIT(a,1) = 0
	SET $BIT(a,2) = 0
	SET $BIT(a,3) = 1
	SET $BIT(a,4) = 0
	SET $BIT(a,5) = 0
	SET $BIT(a,6) = 1
	SET $BIT(a,7) = 1
	SET $BIT(a,8) = 0
	// 测试位串中的单个位
	WRITE "bit #2 value: ",$BIT(a,2),!
	WRITE "bit #7 value: ",$BIT(a,7),!
	WRITE "bit #8 value: ",$BIT(a,8),!
	WRITE "bit #13 value: ",$BIT(a,13),!
	// Write the bitstring
	WRITE "bitstring value: "
	FOR x=1:1:8 {
    
    WRITE $BIT(a,x) }
	WRITE !!,"compressed bitstring: "
	ZZDUMP a
}
DHC-APP>d ##class(PHA.TEST.Function).BIT()
bit #2 value: 0
bit #7 value: 1
bit #8 value: 0
bit #13 value: 0
bitstring value: 00100110
 
compressed bitstring:
0000: 90 01 01 00 02 00 05 00 06 00                           ..........

由于Caché用0位填充位串到指定位置,因此下面的示例返回完全相同的位串数据值。但是,请注意,由于未定义#8位,因此压缩位串a与压缩位串b不相同:

/// d ##class(PHA.TEST.Function).BIT1()
ClassMethod BIT1()
{
	SET $BIT(b,3) = 1
	SET $BIT(b,6) = 1
	SET $BIT(b,7) = 1
	// 测试位串中的单个位
	WRITE "bit #2 value: ",$BIT(b,2),!
	WRITE "bit #7 value: ",$BIT(b,7),!
	WRITE "bit #8 value: ",$BIT(b,8),!
	WRITE "bit #13 value: ",$BIT(b,13),!
	// Write the bitstring
	WRITE "bitstring value: "
	FOR x=1:1:8 {WRITE $BIT(b,x) }
	WRITE !!,"compressed bitstring: "
	ZZDUMP b
}
DHC-APP>d ##class(PHA.TEST.Function).BIT1()
bit #2 value: 0
bit #7 value: 1
bit #8 value: 0
bit #13 value: 0
bitstring value: 0010011000000
 
compressed bitstring:
0000: 91 01 01 00 02 00 05 00 06 00                           ..........

因此,建议始终在位串中始终显式设置最高定义的位(即使其分配的值为0)也是建议的编程习惯。

可以使用FOR expr逗号分隔列表来设置多个位,如以下示例所示:

/// d ##class(PHA.TEST.Function).BIT2()
ClassMethod BIT2()
{
    
    
	FOR i=3,6,7 {
    
     SET $BIT(b,i) = 1 }
	// 测试位串中的单个位
	WRITE "bit #2 value: ",$BIT(b,2),!
	WRITE "bit #7 value: ",$BIT(b,7),!
	WRITE "bit #8 value: ",$BIT(b,8),!
	WRITE "bit #13 value: ",$BIT(b,13),!
	// Write the bitstring
	WRITE "bitstring value: "
	FOR x=1:1:9 {
    
    WRITE $BIT(b,x) }
	WRITE !!,"compressed bitstring: "
	ZZDUMP b
}
DHC-APP>d ##class(PHA.TEST.Function).BIT2()
bit #2 value: 0
bit #7 value: 1
bit #8 value: 0
bit #13 value: 0
bitstring value: 001001100
 
compressed bitstring:
0000: 91 01 01 00 02 00 05 00 06 00                           ..........

在下面的示例中,连续调用$BIT返回由$FACTOR生成的位串的位:

  FOR i=1:1:32 {
    
    WRITE $BIT($FACTOR(2*31-1),i) }
DHC-APP>FOR i=1:1:32 {
    
    WRITE $BIT($FACTOR(2*31-1),i) }
10111100000000000000000000000000

下面的示例返回一个随机的16位位串:

/// d ##class(PHA.TEST.Function).BIT3()
ClassMethod BIT3()
{
    
    
	SET x=$RANDOM(65536)
	w x_":"
	FOR i=1:1:16 {
    
    WRITE $BIT($FACTOR(x),i) }
}
DHC-APP> d ##class(PHA.TEST.Function).BIT3()
50574:0111000110100011
DHC-APP> d ##class(PHA.TEST.Function).BIT3()
52201:1001011111010011
DHC-APP> d ##class(PHA.TEST.Function).BIT3()
9872:0000100101100100
DHC-APP> d ##class(PHA.TEST.Function).BIT3()
46105:1001100000101101
DHC-APP> d ##class(PHA.TEST.Function).BIT3()
36484:0010000101110001
DHC-APP> d ##class(PHA.TEST.Function).BIT3()
18650:0101101100010010

Caché 显示的二进制是从右到左。

有关位串函数的信息

位串函数操作编码的基于位的数据。尽管位串可以与任何CachéObjectScript命令或函数一起使用,但通常仅在位函数的上下文中才有意义。

$BIT位字符串函数执行原子操作。因此,执行位串操作时不需要锁定。

$BIT位串函数执行位串的内部压缩。因此,位串的实际数据长度及其物理空间分配可能会有所不同。$BIT位串函数使用位串的数据长度。在大多数情况下,物理空间分配对于用户而言是不可见的。 $BIT函数的用户看不到位串压缩。

但是,由于此压缩二进制表示针对每个位串进行了优化,因此不能假设两个“相同”的位串(创建方式不同)具有相同的内部表示。 Caché从四个单独的位串内部表示中进行选择,以针对稀疏位串和非稀疏位串进行优化。因此,尽管对单个位进行匹配操作会产生可预测的结果,但整个位串的比较可能不会。

$BIT位串函数支持Caché的最大位串长度为262,104位(32763 x 8)。 (与某些InterSystems旧产品不同,在Caché中对超出位串长度的位执行操作不是错误。)但是,出于性能原因,强烈建议将长位串分成少于65,280的块位。这是一个8KB数据库块中可以容纳的最大位数。

位串中的位以第一个(最左侧)位为位置1进行编号。所有位串比较都是从左到右执行的。

在示例中,位串显示在匹配的方括号([...])中,位以逗号分隔。例如,四个1位的位串显示为[1,1,1,1],最低有效位在右侧。

在所有的位串函数中,名为bitstring的变量是可以指定为值,变量或表达式的位串。

$BIT函数和$ZBIT函数

$BIT函数替代了早期的$ZBIT函数。新代码只能使用$BIT函数;传统应用程序将继续支持$ZBIT功能。$BIT函数和$ZBIT函数不兼容; $BIT函数压缩位串,$ZBIT函数不压缩。因此,不应在同一位串上使用这两种类型的位串函数。尝试这样做会导致<Invalid bit string>错误。

可以使用$SYSTEM.Bit.ZBitToBit()方法将$ZBIT格式的位字符串转换为$ BIT格式的位字符串。在下面的示例中显示:

/// d ##class(PHA.TEST.Function).BITToZBIT()
ClassMethod BITToZBIT()
{
    
    
ZBitSet
	SET zb=$ZBITSTR(4,1)       /* the $ZBIT string 1111 */
	SET zbnew=$ZBITSET(zb,2,0) /* the $ZBIT string 1011 */
ZBitToBit
	SET bb=$SYSTEM.Bit.ZBitToBit(zbnew)
	WRITE !,$BIT(bb,1),$BIT(bb,2),$BIT(bb,3),$BIT(bb,4)
}

DHC-APP>d ##class(PHA.TEST.Function).BITToZBIT()
 
1011

猜你喜欢

转载自blog.csdn.net/yaoxin521123/article/details/108179440