Boolean: Difference between revisions

From QB64 Phoenix Edition Wiki
Jump to navigation Jump to search
No edit summary
Tag: Reverted
No edit summary
 
(58 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''Boolean''' statements are evaluations that return '''true''' (-1) or '''false''' (0) values, such as the [[Relational Operations]]. The results can be used in other arithmetic or logical operations.
'''Boolean''' statements are evaluations that return '''true''' (-1) or '''false''' (0) values. This are for instance the [[Relational Operations]], but also functions such as [[_FILEEXISTS]], [[EOF]], [[_SCREENEXISTS]] etc. return those values when checking for certain conditions. The results of those evaluations or function calls can be used in other mathematical or logical operations.




Line 7: Line 7:
== Relational Operations ==
== Relational Operations ==
* '''True''' relational evaluations return '''-1''', which can be used to increment or decrement a value by using the appropriate operations:
* '''True''' relational evaluations return '''-1''', which can be used to increment or decrement a value by using the appropriate operations:
** I.e. exchange addition and substraction (due to the negative sign) or use [[ABS]] on the result first.
** either use addition to decrement and substraction to increment (due to the negative sign),
* '''False''' relational evaluations return '''0'''. Watch out for [[ERROR Codes|"Division by 0" errors]] here.
** or [[ABS]] the result first and then use substraction to decrement and addition to increment.
* '''False''' relational evaluations return '''0'''. Watch out for [[ERROR Codes|Division by 0]] errors here, if divisions are involved in the further processing.




Line 23: Line 24:


{{PageExamples}}
{{PageExamples}}
;*Example 1:Using 2 different boolean evaluations to determine a leap year.
;Example 1:Using 2 different boolean evaluations to determine a leap year.
 
;Explanation:Both boolean evaluations will return -1 if the year is a leap year. It is not simply every four years as many people think (see [[Wikipedia:Leap year#Gregorian_calendar|Wikipedia]]). That is checked by the first evaluation {{InlineCode}}(Y {{Cl|MOD}} 4 = 0){{InlineCodeEnd}} of each. In new century years like 1900 (which was not a leapyear) there is only one leap year every 400 years. 100 is used with [[MOD]] to see if there is a remainder. When that is true, the boolean return of that part of the first evaluation will be 0. The second returns -1 (which is actually added). In both evaluations the result of {{InlineCode}}(Y {{Cl|MOD}} 400 = 0){{InlineCodeEnd}} indicates a century leap year.
;*Explanation:Both boolean evaluations will return -1 if the year is a leap year. It is not simply every four years as many people think. (see [https://en.wikipedia.org/wiki/Leap_year#Algorithm Wikipedia])
:*That is checked by the first evaluation (Y MOD 4 = 0) of each.
:*In new century years like 1900 (which was not a leapyear) there is only one leap year every 400 years. 100 is used with [[MOD]] to see if there is a remainder. When that is true, the boolean return of that part of the first evaluation will be 0. The second returns -1 (which is actually added).
;*In both evaluations the result of (Y MOD 400 = 0) indicates a century leap year.  
{{CodeStart}}
{{CodeStart}}
{{Cl|INPUT}} "Enter a year greater than 1583: ", annum$
{{Cl|INPUT}} {{Text|<nowiki>"Enter a year greater than 1583: "</nowiki>|#FFB100}}, annum$
Y = {{Cl|VAL}}(annum$)
Y = {{Cl|VAL}}(annum$)
leap1 = (Y {{Cl|MOD}} 4 = 0 AND Y {{Cl|MOD}} 100 <> 0) OR (Y {{Cl|MOD}} 400 = 0)
leap1 = (Y {{Cl|MOD}} {{Text|4|#F580B1}} = {{Text|0|#F580B1}} {{Cl|AND}} Y {{Cl|MOD}} {{Text|100|#F580B1}} <> {{Text|0|#F580B1}}) {{Cl|OR}} (Y {{Cl|MOD}} {{Text|400|#F580B1}} = {{Text|0|#F580B1}})
leap2 = (Y {{Cl|MOD}} 4 = 0) - (Y {{Cl|MOD}} 100 = 0) + (Y {{Cl|MOD}} 400 = 0)
leap2 = (Y {{Cl|MOD}} {{Text|4|#F580B1}} = {{Text|0|#F580B1}}) - (Y {{Cl|MOD}} {{Text|100|#F580B1}} = {{Text|0|#F580B1}}) + (Y {{Cl|MOD}} {{Text|400|#F580B1}} = {{Text|0|#F580B1}})
PRINT "Year = "; annum$, "Leap1 = "; leap1, "Leap2 = "; leap2
{{Cl|PRINT}} {{Text|<nowiki>"Year = "</nowiki>|#FFB100}}; annum$, {{Text|<nowiki>"Leap1 = "</nowiki>|#FFB100}}; leap1, {{Text|<nowiki>"Leap2 = "</nowiki>|#FFB100}}; leap2
{{CodeEnd}}
{{CodeEnd}}
;Entry year = 2000
{{PreStart}}
:leap1 = (-1 AND 0) OR -1 = -1 ' the AND evaluation returns False(0) so the OR value is used.
'''Evaluation for year 2000'''
:leap2 = (-1) - (-1) + (-1) = -1 + 1 + -1 = -1
leap1 = (-1 AND 0) OR -1 = -1 'the AND evaluation is false(0), so the OR value is used
;Entry year = 1900
leap2 = (-1) - (-1) + (-1) = -1 + 1 + -1 = -1
:leap1 = (-1 AND 0) OR 0 = 0 OR 0 = 0
'''Evaluation for year 1900'''
:leap2 = (-1) - (-1) + (0) = -1 + 1 + 0 = 0
leap1 = (-1 AND 0) OR 0 = 0 OR 0 = 0
leap2 = (-1) - (-1) + (0) = -1 + 1 + 0 = 0
{{PreEnd}}


----


;Example 2
;Example 2
:Moving an [[ASCII]] character using the arrow keys and boolean statements to determine the new coordinate.
:Moving an [[ASCII]] character using the arrow keys and boolean statements to determine the new coordinate.
{{CodeStart}}
{{CodeStart}}
{{Cl|SCREEN}} 12
{{Cl|SCREEN}} {{Text|12|#F580B1}}
{{Cl|COLOR}} 7
{{Cl|COLOR}} {{Text|7|#F580B1}}
{{Cl|LOCATE}} 11, 20: {{Cl|PRINT}} "Using Screen 12 here to be in 80 X 30 coordinates mode"
{{Cl|LOCATE}} {{Text|11|#F580B1}}, {{Text|20|#F580B1}}: {{Cl|PRINT}} {{Text|<nowiki>"Using Screen 12 here to be in 80 X 30 coordinates mode"</nowiki>|#FFB100}}
{{Cl|LOCATE}} 13, 6: {{Cl|PRINT}} "Simple Example of Alternative programming without IF-{{Cl|THEN}}-{{Cl|ELSE}} Statements"
{{Cl|LOCATE}} {{Text|13|#F580B1}}, {{Text|6|#F580B1}}: {{Cl|PRINT}} {{Text|<nowiki>"Simple Example of Alternative programming without IF-THEN-ELSE Statements"</nowiki>|#FFB100}}
{{Cl|LOCATE}} 15, 1: {{Cl|PRINT}} "Use the four Cursor keys to move the yellow cursor, text will not be disturbed"
{{Cl|LOCATE}} {{Text|15|#F580B1}}, {{Text|1|#F580B1}}: {{Cl|PRINT}} {{Text|<nowiki>"Use the four Cursor keys to move the yellow cursor, text will not be disturbed"</nowiki>|#FFB100}}
{{Cl|LOCATE}} 17, 12: {{Cl|PRINT}} "When you {{Cl|END}} the program with the ESC key, cursor will disappear"
{{Cl|LOCATE}} {{Text|17|#F580B1}}, {{Text|12|#F580B1}}: {{Cl|PRINT}} {{Text|<nowiki>"When you END the program with the ESC key, cursor will disappear"</nowiki>|#FFB100}}


cordx% = 40
cordx% = {{Text|40|#F580B1}}
cordy% = 15
cordy% = {{Text|15|#F580B1}}


{{Cl|DO...LOOP|DO}}
{{Cl|DO}}
oldcordx% = cordx%
    oldcordx% = cordx%
oldcordy% = cordy%
    oldcordy% = cordy%
p% = {{Cl|SCREEN (function)|SCREEN}}(cordy%, cordx%) 'get ASCII character code at present position
    p% = {{Cl|SCREEN (function)|SCREEN}}(cordy%, cordx%) {{Text|<nowiki>'get ASCII character code at present position</nowiki>|#919191}}
{{Cl|COLOR}} 14: {{Cl|LOCATE}} cordy%, cordx%: {{Cl|PRINT}} {{Cl|CHR$}}(178); 'print cursor character to position
    {{Cl|COLOR}} {{Text|14|#F580B1}}: {{Cl|LOCATE}} cordy%, cordx%: {{Cl|PRINT}} {{Cl|CHR$}}({{Text|178|#F580B1}}); {{Text|<nowiki>'print cursor character to position</nowiki>|#919191}}


{{Cl|WHILE}} cordx% = oldcordx% {{Cl|AND (boolean)|AND}} cordy% = oldcordy% {{Cl|AND (boolean)|AND}} k$ <> {{Cl|CHR$}}(27)
    {{Cl|WHILE}} cordx% = oldcordx% {{Cl|AND (boolean)|AND}} cordy% = oldcordy% {{Cl|AND (boolean)|AND}} k$ <> {{Cl|CHR$}}({{Text|27|#F580B1}})
k$ = {{Cl|INKEY$}}
        k$ = {{Cl|INKEY$}}
cordx% = cordx% + (k$ = ({{Cl|CHR$}}(0) + "K") {{Cl|AND (boolean)|AND}} cordx% > 1) + {{Cl|ABS}}(k$ = ({{Cl|CHR$}}(0) + "M") {{Cl|AND (boolean)|AND}} cordx% < 80)
        cordx% = cordx% + (k$ = ({{Cl|CHR$}}({{Text|0|#F580B1}}) + {{Text|<nowiki>"K"</nowiki>|#FFB100}}) {{Cl|AND}} cordx% > {{Text|1|#F580B1}}) + {{Cl|ABS}}(k$ = ({{Cl|CHR$}}({{Text|0|#F580B1}}) + {{Text|<nowiki>"M"</nowiki>|#FFB100}}) {{Cl|AND}} cordx% < {{Text|80|#F580B1}})
cordy% = cordy% + (k$ = ({{Cl|CHR$}}(0) + "H") {{Cl|AND (boolean)|AND}} cordy% > 1) + {{Cl|ABS}}(k$ = ({{Cl|CHR$}}(0) + "P") {{Cl|AND (boolean)|AND}} cordy% < 30)
        cordy% = cordy% + (k$ = ({{Cl|CHR$}}({{Text|0|#F580B1}}) + {{Text|<nowiki>"H"</nowiki>|#FFB100}}) {{Cl|AND}} cordy% > {{Text|1|#F580B1}}) + {{Cl|ABS}}(k$ = ({{Cl|CHR$}}({{Text|0|#F580B1}}) + {{Text|<nowiki>"P"</nowiki>|#FFB100}}) {{Cl|AND}} cordy% < {{Text|30|#F580B1}})
{{Cl|WEND}}
    {{Cl|WEND}}


{{Cl|COLOR}} 7: {{Cl|LOCATE}} oldcordy%, oldcordx%: {{Cl|PRINT}} {{Cl|CHR$}}(p%); 'replace overwritten screen characters
    {{Cl|COLOR}} {{Text|7|#F580B1}}: {{Cl|LOCATE}} oldcordy%, oldcordx%: {{Cl|PRINT}} {{Cl|CHR$}}(p%); {{Text|<nowiki>'replace overwritten screen characters</nowiki>|#919191}}


{{Cl|LOOP}} {{Cl|UNTIL}} k$ = {{Cl|CHR$}}(27)
{{Cl|DO...LOOP|LOOP UNTIL}} k$ = {{Cl|CHR$}}({{Text|27|#F580B1}})
{{CodeEnd}}
{{CodeEnd}}
{{small|Code by AlgoreIthm}}
{{Small|Code by AlgoreIthm}}




Line 80: Line 80:
* [[Binary]], [[ABS]], [[SGN]]
* [[Binary]], [[ABS]], [[SGN]]
* [[AND]], [[OR]], [[XOR]]
* [[AND]], [[OR]], [[XOR]]
* [https://qb64forum.alephc.xyz/index.php?topic=4648 True and False (Forum discussion)]
* [[Bitwise Operators|Bitwise Operations]]




{{PageNavigation}}
{{PageReferences}}

Latest revision as of 12:26, 19 November 2024

Boolean statements are evaluations that return true (-1) or false (0) values. This are for instance the Relational Operations, but also functions such as _FILEEXISTS, EOF, _SCREENEXISTS etc. return those values when checking for certain conditions. The results of those evaluations or function calls can be used in other mathematical or logical operations.


Relational Operations

  • True relational evaluations return -1, which can be used to increment or decrement a value by using the appropriate operations:
    • either use addition to decrement and substraction to increment (due to the negative sign),
    • or ABS the result first and then use substraction to decrement and addition to increment.
  • False relational evaluations return 0. Watch out for Division by 0 errors here, if divisions are involved in the further processing.


Logical Operations

  • Any of the logical operations can be used to further process or combine several conditions, but most useful are:
    • AND to add extra conditions to a boolean statement evaluation.
    • OR to add alternate conditions to a boolean statement evaluation.
  • Parenthesis are allowed inside of boolean statements to clarify an evaluation.


         Table 3: The relational operations for condition checking.

 In this table, A and B are the Expressions to compare. Both must represent
 the same general type, i.e. they must result into either numerical values
 or STRING values. If a test succeeds, then true (-1) is returned, false (0)
     if it fails, which both can be used in further Boolean evaluations.
 ┌─────────────────────────────────────────────────────────────────────────┐
 │                          Relational Operations                          │
 ├────────────┬───────────────────────────────────────────┬────────────────┤
 │ OperationDescriptionExample usage  │
 ├────────────┼───────────────────────────────────────────┼────────────────┤
 │   A = B    │ Tests if A is equal to B.                 │ IF A = B THEN  │
 ├────────────┼───────────────────────────────────────────┼────────────────┤
 │   A <> B   │ Tests if A is not equal to B.             │ IF A <> B THEN │
 ├────────────┼───────────────────────────────────────────┼────────────────┤
 │   A < B    │ Tests if A is less than B.                │ IF A < B THEN  │
 ├────────────┼───────────────────────────────────────────┼────────────────┤
 │   A > B    │ Tests if A is greater than B.             │ IF A > B THEN  │
 ├────────────┼───────────────────────────────────────────┼────────────────┤
 │   A <= B   │ Tests if A is less than or equal to B.    │ IF A <= B THEN │
 ├────────────┼───────────────────────────────────────────┼────────────────┤
 │   A >= B   │ Tests if A is greater than or equal to B. │ IF A >= B THEN │
 └────────────┴───────────────────────────────────────────┴────────────────┘
   The operations should be very obvious for numerical values. For strings
   be aware that all checks are done case sensitive (i.e. "Foo" <> "foo").
   The equal/not equal check is pretty much straight forward, but for the
   less/greater checks the ASCII value of the first different character is
                          used for decision making:

   E.g. "abc" is less than "abd", because in the first difference (the 3rd
        character) the "c" has a lower ASCII value than the "d".

   This behavior may give you some subtle results, if you are not aware of
                   the ASCII values and the written case:

   E.g. "abc" is greater than "abD", because the small letters have higher
        ASCII values than the capital letters, hence "c" > "D". You may use
        LCASE$ or UCASE$ to make sure both strings have the same case.
               Table 4: The logical operations and its results.

       In this table, A and B are the Expressions to invert or combine.
              Both may be results of former Boolean evaluations.
  ┌────────────────────────────────────────────────────────────────────────┐
  │                           Logical Operations                           │
  ├───────┬───────┬───────┬─────────┬────────┬─────────┬─────────┬─────────┤
  │   ABNOT BA AND BA OR BA XOR BA EQV BA IMP B │
  ├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
  │ truetrue  │ false │  true   │ true   │  false  │  true   │  true   │
  ├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
  │ truefalse │ true  │  false  │ true   │  true   │  false  │  false  │
  ├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
  │ falsetrue  │ false │  false  │ true   │  true   │  false  │  true   │
  ├───────┼───────┼───────┼─────────┼────────┼─────────┼─────────┼─────────┤
  │ falsefalse │ true  │  false  │ false  │  false  │  true   │  true   │
  └───────┴───────┴───────┴─────────┴────────┴─────────┴─────────┴─────────┘
   Note: In most BASIC languages incl. QB64 these are bitwise operations,
         hence the logic is performed for each corresponding bit in both
         operators, where true or false indicates whether a bit is set or
         not set. The outcome of each bit is then placed into the respective
         position to build the bit pattern of the final result value.

   As all Relational Operations return negative one (-1, all bits set) for
    true and zero (0, no bits set) for false, this allows us to use these
    bitwise logical operations to invert or combine any relational checks,
    as the outcome is the same for each bit and so always results into a
            true (-1) or false (0) again for further evaluations.


Examples

Example 1
Using 2 different boolean evaluations to determine a leap year.
Explanation
Both boolean evaluations will return -1 if the year is a leap year. It is not simply every four years as many people think (see Wikipedia). That is checked by the first evaluation (Y MOD 4 = 0) of each. In new century years like 1900 (which was not a leapyear) there is only one leap year every 400 years. 100 is used with MOD to see if there is a remainder. When that is true, the boolean return of that part of the first evaluation will be 0. The second returns -1 (which is actually added). In both evaluations the result of (Y MOD 400 = 0) indicates a century leap year.
INPUT "Enter a year greater than 1583: ", annum$
Y = VAL(annum$)
leap1 = (Y MOD 4 = 0 AND Y MOD 100 <> 0) OR (Y MOD 400 = 0)
leap2 = (Y MOD 4 = 0) - (Y MOD 100 = 0) + (Y MOD 400 = 0)
PRINT "Year = "; annum$, "Leap1 = "; leap1, "Leap2 = "; leap2
Evaluation for year 2000
 leap1 = (-1 AND 0) OR -1 = -1 'the AND evaluation is false(0), so the OR value is used
 leap2 = (-1) - (-1) + (-1) = -1 + 1 + -1 = -1
Evaluation for year 1900
 leap1 = (-1 AND 0) OR 0 = 0 OR 0 = 0
 leap2 = (-1) - (-1) + (0) = -1 + 1 + 0 = 0

Example 2
Moving an ASCII character using the arrow keys and boolean statements to determine the new coordinate.
SCREEN 12
COLOR 7
LOCATE 11, 20: PRINT "Using Screen 12 here to be in 80 X 30 coordinates mode"
LOCATE 13, 6: PRINT "Simple Example of Alternative programming without IF-THEN-ELSE Statements"
LOCATE 15, 1: PRINT "Use the four Cursor keys to move the yellow cursor, text will not be disturbed"
LOCATE 17, 12: PRINT "When you END the program with the ESC key, cursor will disappear"

cordx% = 40
cordy% = 15

DO
    oldcordx% = cordx%
    oldcordy% = cordy%
    p% = SCREEN(cordy%, cordx%) 'get ASCII character code at present position
    COLOR 14: LOCATE cordy%, cordx%: PRINT CHR$(178); 'print cursor character to position

    WHILE cordx% = oldcordx% AND cordy% = oldcordy% AND k$ <> CHR$(27)
        k$ = INKEY$
        cordx% = cordx% + (k$ = (CHR$(0) + "K") AND cordx% > 1) + ABS(k$ = (CHR$(0) + "M") AND cordx% < 80)
        cordy% = cordy% + (k$ = (CHR$(0) + "H") AND cordy% > 1) + ABS(k$ = (CHR$(0) + "P") AND cordy% < 30)
    WEND

    COLOR 7: LOCATE oldcordy%, oldcordx%: PRINT CHR$(p%); 'replace overwritten screen characters

LOOP UNTIL k$ = CHR$(27)
Code by AlgoreIthm


See also


QB64 Programming References

Wiki Pages
Main Page with Articles and Tutorials
QB64 specific keywords (alphabetical)
Original QBasic keywords (alphabetical)
QB64 OpenGL keywords (alphabetical)
Keywords by Usage
Got a question about something?
Frequently Asked Questions about QB64
QB64 Phoenix Edition Community Forum
Links to other QBasic Sites:
Pete's QBasic Forum
Pete's QBasic Downloads