HP Forums

Full Version: [BUG] Logical AND
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hi,

Could not find any report of this elsewhere

If you are in Home View
3 AND 2 returns 1

However if you are in CAS
3 AND 2 returns 2

If you try 3 and 2, it still returns 2 and the and is changed to AND on the line

The other logical operators seems to behave as expected.

Cheers, Terje
I beleive it is doing a bitwise and here by design. You are comparing two integers after all.
(01-26-2014 04:27 PM)Tim Wessman Wrote: [ -> ]I beleive it is doing a bitwise and here by design. You are comparing two integers after all.

Hi,

I may be mistaken but shouldn't then a bitwise 5 AND 3 become 1 rather than 3 on the calculator? The result is in any event the same if you use 3. AND 2.

In Home view there seems to be no such bitwise manipulation

Also the help screen on the calculator uses 3 AND 2 -> 1 as an example...

Cheers, Terje
In Home it turn to bitwise with binary integer
#2 AND #3 is bitwise
It is undocumented. It overlap with BITAND()
EXPR("3 AND 2") always return 1. Something funny is happening in the CAS, it always returns the last digit.
Yep, for (x and y) CAS returns (x!=0)*y
i.e. 0 and y returns 0 while x and y returns y for any x<>0
Prime have 2 heads: Home and CAS
So using a CAS function in Home get you some CAS behavior in Home.
And the same function can exist in both, simply Home will be uppercase and CAS will be lowercase.
(01-26-2014 05:16 PM)patrice Wrote: [ -> ]Prime have 2 heads: Home and CAS
So using a CAS function in Home get you some CAS behavior in Home.
And the same function can exist in both, simply Home will be uppercase and CAS will be lowercase.
CAS makes it uppercase after you press enter.
Documentation is the same in both cases.
What the heck is the advantage of the CAS implementation?

Doesn't make much sense to me. Definitely a bug.
Quote:I may be mistaken but shouldn't then a bitwise 5 AND 3 become 1 rather than 3 on the calculator? The result is in any event the same if you use 3. AND 2

Well I thought it was doing a bitwise, but you are right. Just seems to be returning the second item. Maybe bernard can enlighten. :-?
a and b returns 0 if a is zero and b otherwise for integers. Returning b is easier than returning 1 because it works for other types (e.g. if b is a variable name or a symbolic expression). For more precision, here is the source code from gen.cc
Code:

  gen operator && (const gen & a,const gen & b){
    if (is_zero(a,context0)){
      if (b.type==_DOUBLE_)
    return 0.0;
      if (b.type==_FLOAT_)
    return giac_float(0);
      return !is_zero(a);
    }
    if (is_zero(b,context0)){
      if (a.type==_DOUBLE_ )
    return 0.0;
      if (a.type==_FLOAT_)
    return giac_float(0);
      return !is_zero(b);
    }
    if (a.type<=_CPLX || a.type==_FLOAT_)
      return b;
    if (b.type<=_CPLX || b.type==_FLOAT_)
      return a;
    if (a.is_symb_of_sommet(at_and)){
      if (b.is_symb_of_sommet(at_and))
    return new_ref_symbolic(symbolic(at_and,gen(mergevecteur(*a._SYMBptr->feuille._VECTptr,*b._SYMBptr->feuille._VECTptr),_SEQ__VECT)));
      vecteur v=*a._SYMBptr->feuille._VECTptr;
      v.push_back(b);
      return new_ref_symbolic(symbolic(at_and,v));
    }
    if (b.is_symb_of_sommet(at_and)){
      vecteur v=*b._SYMBptr->feuille._VECTptr;
      v.push_back(a);
      return new_ref_symbolic(symbolic(at_and,v));
    }
    if ( ((a.type==_IDNT) || (a.type==_SYMB)) || ((a.type==_IDNT) || (a.type==_SYMB)) )
      return symb_and(a,b);
    if ( (a.type==_DOUBLE_) || (b.type==_DOUBLE_) )
      return 1.0;
    if ( (a.type==_FLOAT_) || (b.type==_FLOAT_) )
      return giac_float(1);
    return plus_one;
  }
Can you please fix that to 1:true and 0:false?
==0 for False and <>0 for True is not worse than ==1 for False
In some occasions, I like to do arithmetic with tests. Something like (a==b)*c+d with the test returning 1 or 0 is very convenient.
(01-27-2014 10:53 PM)Tugdual Wrote: [ -> ]In some occasions, I like to do arithmetic with tests. Something like (a==b)*c+d with the test returning 1 or 0 is very convenient.
Then test ((a<>0)==(b<>0))*(c<>0)+(d<>0)
(01-27-2014 11:53 PM)Han Wrote: [ -> ]Just use AND as opposed to and (lower case). The uppercase version does not have this behavior and will evaluate to either a 0 or a 1, or produce an error otherwise (if I'm not mistaken). This goes for both Home and CAS view.

In this case I think you may be mistaken. If you refer to my initial post, I tried both upper- and lowercase and, both with the same result. In CAS mode the lowercase and is changed to uppercase after the command is executed.

Cheers, Terje
(01-27-2014 09:20 AM)parisse Wrote: [ -> ]a and b returns 0 if a is zero and b otherwise for integers. Returning b is easier than returning 1 because it works for other types (e.g. if b is a variable name or a symbolic expression). For more precision, here is the source code from gen.cc
Code:

  gen operator && (const gen & a,const gen & b){
    if (is_zero(a,context0)){
      if (b.type==_DOUBLE_)
    return 0.0;
      if (b.type==_FLOAT_)
    return giac_float(0);
      return !is_zero(a);
    }
    if (is_zero(b,context0)){
      if (a.type==_DOUBLE_ )
    return 0.0;
      if (a.type==_FLOAT_)
    return giac_float(0);
      return !is_zero(b);
    }
    if (a.type<=_CPLX || a.type==_FLOAT_)
      return b;
    if (b.type<=_CPLX || b.type==_FLOAT_)
      return a;
    if (a.is_symb_of_sommet(at_and)){
      if (b.is_symb_of_sommet(at_and))
    return new_ref_symbolic(symbolic(at_and,gen(mergevecteur(*a._SYMBptr->feuille._VECTptr,*b._SYMBptr->feuille._VECTptr),_SEQ__VECT)));
      vecteur v=*a._SYMBptr->feuille._VECTptr;
      v.push_back(b);
      return new_ref_symbolic(symbolic(at_and,v));
    }
    if (b.is_symb_of_sommet(at_and)){
      vecteur v=*b._SYMBptr->feuille._VECTptr;
      v.push_back(a);
      return new_ref_symbolic(symbolic(at_and,v));
    }
    if ( ((a.type==_IDNT) || (a.type==_SYMB)) || ((a.type==_IDNT) || (a.type==_SYMB)) )
      return symb_and(a,b);
    if ( (a.type==_DOUBLE_) || (b.type==_DOUBLE_) )
      return 1.0;
    if ( (a.type==_FLOAT_) || (b.type==_FLOAT_) )
      return giac_float(1);
    return plus_one;
  }

Is there some convention that xcas/giac is following by returning the second argument if the first argument is non-zero in an AND operation? This is the first time I've seen a non-bitwise AND operation return something other than the operation unevaluated, 0, or 1 (or some variation of the values 0 and 1) on atomic arguments.
(01-27-2014 11:59 PM)Terje Vallestad Wrote: [ -> ]
(01-27-2014 11:53 PM)Han Wrote: [ -> ]Just use AND as opposed to and (lower case). The uppercase version does not have this behavior and will evaluate to either a 0 or a 1, or produce an error otherwise (if I'm not mistaken). This goes for both Home and CAS view.

In this case I think you may be mistaken. If you refer to my initial post, I tried both upper- and lowercase and, both with the same result. In CAS mode the lowercase and is changed to uppercase after the command is executed.

Cheers, Terje

Believe it or not (this is SO bizarre), you can use this mixed-case syntax in CAS only:

And(x,y)

It returns 0 or 1, as you wanted. If Textbook Display is off, it will nicely be displayed in the history as "And", the way you typed it. (That's true for most commands when Textbook Display is off). If Textbook Display is on, it will annoyingly be displayed as "AND" but it will still act like "And", the way you want it to.

If the "Change apparent integers into exact integers" CAS setting is turned off, then it will return the reals 0. and 1. instead of the integers 0 and 1, as shown below, but that shouldn't matter.

[Image: And.png]
There is a reason not to return 1, if you run say 2 && a, where a is symbolic, it's better to return a than 1 since if a is 0 the answer is correct. What I can do is change to 1 (or 0) if the second argument is a float or complex or integer.
I am beginning to realize that the AND, OR, and NOT from the Shift+6 menu are more meant for Boolean tests (true vs false) - while BITAND, BITOR, and BITNOT are for Boolean operations.
Hi Eddie,
(01-30-2014 01:49 PM)Eddie W. Shore Wrote: [ -> ]I am beginning to realize that the AND, OR, and NOT from the Shift+6 menu are more meant for Boolean tests (true vs false) - while BITAND, BITOR, and BITNOT are for Boolean operations.
I don't know if it is a usage or not, but I call "Boolean" operations done at integer value level, and "bitwise" operations done at bit level.

AND, OR and NOT are said to be Boolean.
BITAND, BITOR, BITNOT and BITXOR are said to be bitwise (operations done at bit level.

So:
3 OR 5 => 1, Boolean as expected
BITOR(3,5) => 7, bitwise as expected
but
#3 OR #5 => #7, bitwise not as expected
BITOR(#3,#5) => #7, bitwise as expected

in order to get OR to act Boolean, one have to resort to:
(#3 <> #0) OR '#5 <> #0)

Unfortunate behavior!
Pages: 1 2
Reference URL's