problems reading bit vectors

Posted by Gdub on Wed 01 May 2024 03:54 PM — 5 posts, 9,335 views.

#0
I'm having trouble reading an extended bit vector. I'm trying to use the isflagged functionality from SMAUGFUSS ported into SMAUG 1.4a. Everything is compiling, being set and reading/saving from disc (as far as I can tell) but there's a strange conversion error when ifchecking and reading the flag.


setting flag:


mpflag noexpire $n justtesting 2


checking flag:

if isflagged($n,justtesting,2)
mpecho checking isflagged for $n - $n has a flag
else
mpe isflagged not working yet.
endif


vstat

  Vnum: 3          Tag: justtesting     Timer: 0
  Type: XBIT       Data: [1 1]


pfile

#VARIABLE
Type    2
Flags   0
Vnum    3
Ctime   1714581585
Mtime   1714581783
Rtime   0
Timer   0
Tag     justtesting~
Xbit    6
End


when stepping through the code - specifically in the "isflagged" portion of mprog_do_ifcheck(). The flag is being read as '2' which what is the value being set in script but once it does the flag = abs(flag) % MAX_BITS; it is converted to '64' and then returns as false or unset.


	flag = abs(flag) % MAX_BITS;  // hrmm, Vooodoo
	switch (vd->type)
	{
		case vtSTR:
		case vtINT:
			return FALSE;
		case vtXBIT:
		if (xIS_SET(*(EXT_BV*)vd->data, flag) == TRUE)
		{
			bFlag = TRUE;
		}
		else
		{
			bFlag = FALSE;
		}
		return bFlag;

	}



defines:

#define xIS_SET(var, bit)	((var).bits[(bit) >> RSV] & 1 << ((bit) & XBM))
#define xSET_BIT(var, bit)	((var).bits[(bit) >> RSV] |= 1 << ((bit) & XBM))

#ifndef INTBITS
  #define INTBITS	32
#endif
#define XBM		31	/* extended bitmask   ( INTBITS - 1 )	*/
#define RSV		5	/* right-shift value  ( sqrt(XBM+1) )	*/
#define XBI		4	/* integers in an extended bitvector	*/
#define MAX_BITS	XBI * INTBITS

Amended on Wed 01 May 2024 06:39 PM by Gdub
Australia Forum Administrator #1

		if (xIS_SET(*(EXT_BV*)vd->data, flag) == TRUE)


That is just giving zero if not set and non-zero if set. Don't compare to TRUE.
#2
Nick Gammon said:


		if (xIS_SET(*(EXT_BV*)vd->data, flag) == TRUE)


That is just giving zero if not set and non-zero if set. Don't compare to TRUE.


thanks Nick! That didn't seem to change the results, but a good reminder for me...

Should I try any of the other bit macros?


bool	ext_is_empty		args( ( EXT_BV *bits ) );
void	ext_clear_bits		args( ( EXT_BV *bits ) );
int	    ext_has_bits		args( ( EXT_BV *var, EXT_BV *bits) );
bool	ext_same_bits		args( ( EXT_BV *var, EXT_BV *bits) );
void	ext_set_bits		args( ( EXT_BV *var, EXT_BV *bits) );
void	ext_remove_bits		args( ( EXT_BV *var, EXT_BV *bits) );
void	ext_toggle_bits		args( ( EXT_BV *var, EXT_BV *bits) );

/*
 * Here are the extended bitvector macros:
 */
#define xIS_SET(var, bit)	((var).bits[(bit) >> RSV] & 1 << ((bit) & XBM))
#define xSET_BIT(var, bit)	((var).bits[(bit) >> RSV] |= 1 << ((bit) & XBM))
#define xSET_BITS(var, bit)	(ext_set_bits(&(var), &(bit)))
#define xREMOVE_BIT(var, bit)	((var).bits[(bit) >> RSV] &= ~(1 << ((bit) & XBM)))
#define xREMOVE_BITS(var, bit) (ext_remove_bits(&(var), &(bit)))
#define xTOGGLE_BIT(var, bit)	((var).bits[(bit) >> RSV] ^= 1 << ((bit) & XBM))
#define xTOGGLE_BITS(var, bit) (ext_toggle_bits(&(var), &(bit)))
#define xCLEAR_BITS(var)	(ext_clear_bits(&(var)))
#define xIS_EMPTY(var)		(ext_is_empty(&(var)))
#define xHAS_BITS(var, bit)	(ext_has_bits(&(var), &(bit)))
#define xSAME_BITS(var, bit)	(ext_same_bits(&(var), &(bit)))


commenting this line out makes the flags read properly but I'm not sure what functionality I'm losing by doing this? is it just a guard from combining too many flags and going over the max?


flag = abs(flag) % MAX_BITS; 


why would abs(2) % 128 resolve to 64? Shouldn't it be 2?
Amended on Thu 02 May 2024 02:24 AM by Gdub
Australia Forum Administrator #3
What type does "flag" have?

Yes, 2 % 128 would be 2. I'm not sure why they are using abs there, unless a negative flag has some subtle meaning.
#4

int flag = 0;


this is how its being set


if (argc > 3)
	flag = atoi(argv[3]);


I commented this out and now the entire system works. I am going to consider this resolved for the time being until I run into a bug with it.


 flag = abs(flag) % MAX_BITS;


Thank you Nick, appreciate your help.