123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- \ There are words for true and false:
- true .
- false .
- true hex u. decimal
- \ int equality
- 1 1 = .
- \ check if zero
- 1 0= .
- \ less and greater
- 0 1 < .
- 0 0 < .
- 1 0 > .
- \ is assuming unsigned value, then wrong result
- -1 1 u< .
- \ compare to
- -1 1 < .
- \ boolean words work bitwise. For example:
- 1 2 and .
- \ Will be treated like this:
- \ 0000 0001 (is 1)
- \ and 0000 0010 (is 2)
- \ -> 0000 0000 (is 0)
- \ or written in binary:
- \ %00000001 %00000010 and -> %00000000
- \ Here is an example for or:
- 1 2 or .
- \ 0000 0001 (is 1)
- \ or 0000 0010 (is 2)
- \ -> 0000 0011 (is 3)
- \ boolean words can be used with flags (zero or non-zero)
- \ To make a proper flag out of any integer, you can use 0<>:
- 3 0<> .
- \ 0= checks for all bits being 0. Since false is encoded by 0, this
- \ turns any non-zero into a 0 and any 0 into a -1.
- 3 0= .
- \ Boolean words can replace conditionals:
- : foo ( n1 -- n2 )
- ( if there is not a 0, then write a 14, otherwise write a 0 )
- 0= if 14 else 0 then ;
- : bar ( n1 -- n2 )
- \ -1 has all bits 1 and will not filter anything out when used with
- \ `and` as a bit mask, but if the other argument has a 0 bit
- \ anywhere, the result will also have a 0 bit at that position,
- \ because both bits must be 1 for the resulting bit to be 1. A 0 on
- \ the other hand will have all bits 0, filtering everything out,
- \ when used as a bit mask, resulting in a 0 as a total result.
- 0= 14 and
- \ examples:
- \ 0 0= -> -1
- \ -1 14 -> -1 14
- \ -1 14 and -> 14
- \ 123 0= -> 0
- \ 0 14 -> 0 14
- \ 0 14 and -> 0
- ;
- \ Exercise: Write min without making use of `if`.
- \ Previous version of min:
- : min ( n1 n2 -- n )
- \ Only let the `if` decide whether or not to swap the
- \ arguments.
- 2dup > if swap then
- drop ;
- : min ( n1 n2 -- n )
- 2dup <
- \ 3 1 3dup -> 3 1 3 1
- \ 3 1 3 1 < -> 3 1 0
- \ 3 1 0
- \ seeking something that uses 0 to keep the 1
- \ - - maybe?
- \ ans ?
- \ 3 1 0 or -> 3 1
- \ 3 1 nip -> 1
- \ 1 3 -1 or -> 1 -1
- ;
- : min
- 2dup > 1+ pick nip nip ;
- : min
- 2dup > 1+ roll nip ;
- \ : min
- \ \ 3 1 -- 1 3
- \ \ adds the information, which one is greater
- \ 2dup >
- \ \ 3 1 -1 -- 1 3 0
- \ \ `and` sets the greater value to 0 and keeps the smaller
- \ \ value, because of different result of > (-1 or 0)
- \ and
- \ \ 3 1 -- 1 0
- \ \ tuck stores the smaller number, if it is on top of the
- \ \ stack, at the bottom of the stack. If the smaller number
- \ \ is not at the top of the stack, then it stores a 0 at
- \ \ the bottom of the stack.
- \ tuck
- \ \ After `tuck` we still have either the smaller number on
- \ \ top of the stack or a zero, because of `and` with false
- \ \ (0). However, we also have a "backup" of the smaller
- \ \ number at the bottom of the stack, so that we can work
- \ \ with the top element, without losing the minimum number.
- \ \ 1 3 1 -- 0 1 0
- \ \ 0= will determin, whether we have had the smaller number
- \ \ on top, or a 0 and give 0 or -1 as a result. This makes
- \ \ the actual distinction between the smaller number and 0,
- \ \ as it outputs a -1 for input 0 and a 0 for any other
- \ \ input:
- \ \ If there is a 0, we get a -1, which is all bits set to
- \ \ 1. We only got a 0 on the stack, when the bigger number
- \ \ was on top of the stack initially.
- \ \ If there is a non-zero value, we get a 0, which is all
- \ \ bits set to 0. We only got a 0, if the smaller number
- \ \ was initially on top of the stack. (OR ZERO AS A NUMBER!
- \ \ MISTAKE!)
- \ 0=
- \ \ 1 3 0 -- 0 1 -1
- \ and
- \ \ 1 0 -- 0 1
- \ or
- \ \ 1 -- 1
- \ ;
- : min ( a b - x )
- \ adds the information, which one is greater
- 2dup <
- tuck
- 0=
- and
- -rot and or ;
- \ Test cases:
- 2 0 min .s .
- 0 2 min .s .
- 0 -1 min .s .
- -1 0 min .s .
- 3 1 min .s .
- 1 3 min .s .
|