I would also suggest:
        Add a refinement to pad with leading
zeroes if necessary:

I.E. dec2bin/32 0
>> 00000000000000000000000000000000

Really looks unnecessary, but useful
when illustrating a variable that is of type
integer! and has 32 bits. More of interest
in a teaching situation, which rebol can
be well suited to.
-Tim

At 10:51 AM 8/1/00 -0500, you wrote:
>[EMAIL PROTECTED] wrote:
>> 
>>         Ok, I created my first useful function.
>>
>
>Congratulations!  Good feeling, isn't it?  I always get psyched when I
>get my head around a tool well enough to actually do something with it.
>
>>
>>  I created the following function
>> because enbase/base value 2 gave me a limitation.  So add this script to
>> your %user.r file. Wish this could be added to /Core as it really needs a
>> simple function for this. I hope to post a view based Subnet Calculator
>> soon. Let me know if it helps.
>> 
>> Paul Tretter
>> 
>> dec-to-bin: func[
>>     "Converts Based 10 Integers to Binary"
>>     dn [integer!] "Base 10 Integer"][
>>     holder: copy ""
>>     while [dn / 2 <> 0][
>>         either dn // 2 > 0 [insert holder 1][insert holder 0]
>>         dn: to-integer dn / 2
>>     ]
>>     print holder
>> 
>> ]
>
>Can I make a couple of suggestions?
>
>1)  As written, the function doesn't convert "integers", but only
>    positive integers.  For example:
>
>        >> dec-to-bin -1
>        0
>        >> dec-to-bin -10
>        0000
>        >> dec-to-bin 0
>
>        >>
>
>    Handling these cases will make the function more general.
>
>2)  Since "holder" is not declared local, it shows up in the global
>    context.  This is A Bad Idea.  If there was already a variable
>    or function named "holder", invoking dec-to-bin would clobber it!
>
>3)  Instead of printing the result, why not simply return it?  If
>    the result is returned to an interactive session, it will be
>    printed anyway.  However, making the result available for further
>    processing allows for more general use.  For example, how many
>    bits does it take to hold 4508321?  (see below)
>
>4)  Avoid unnecessary tests whenever possible.  In the line of code
>
>>         either dn // 2 > 0 [insert holder 1][insert holder 0]
>
>    notice that the expression  dn // 2  returns 0 or 1 (for natural
>    dn, but see below), therefore this line can be shortened to
>
>>         insert holder dn // 2
>
>With all of these suggestions implemented, the function looks like
>this (the name change was simply so that I could have both defined
>at once...)
>
>    dec2bin: func[
>        "Converts Based 10 Integers to Binary"
>        dn [integer!] "Base 10 Integer"
>        /local holder "accumulate non-zero results"
>    ][
>        either dn = 0 [
>            "0"
>        ][
>            either dn < 0 [
>                holder: next copy "-"
>                dn: - dn
>            ][
>                holder: copy ""
>            ]
>            while [dn > 0][
>                insert holder dn // 2
>                dn: to-integer dn / 2
>            ]
>            head holder
>        ]
>    ]
>
>And, to check the suggestions...
>
>    >> dec2bin 0
>    == "0"
>    >> dec2bin -1
>    == "-1"
>    >> dec2bin -10
>    == "-1010"
>    >> dec2bin 4508321
>    == "10001001100101010100001"
>
>This last case (from point 3) reminds me to do
>
>    >> length? dec2bin 4508321
>    == 23
>
>About the open issue from point 4, don't bother to read the rest of this if
>you don't care about the mathematics -- the suggested implementation in
>dec2bin avoids signed integer arithmetic and is therefore immune from the
>problem discussed below.
>
>-jn-
>
>REBOL (unfortunately, in my opinion) interprets "to-integer" as
>
>    "the integer part as written out in text",
>
>rather than the more mathematically correct
>
>    "largest integer not exceeding"
>
>(and REBOL is not alone in this).  What this means is that we get
>
>    >> -5 // 2
>    == -2.5
>    >> to-integer -5 / 2
>    == -2
>
>Now, based on the definition of remainder, / and // MUST satisfy (for
>integral a and b)
>
>    a = b * (to-integer a / b) + (a // b)
>
>which backs us into the weird case that
>
>    >> -5 // 2
>    == -1
>
>Why is this weird?  There's lots of useful mathematics (and several
>useful programming techniques, as well) based on the idea that the
>modulus (remainder after division) is ALWAYS bounded between zero
>and (divisor - 1).  For example, think about "clock arithmetic"
>using a 24-hour clock (in which the hours run from 0 to 23).  To
>get the hour that is thirteen hours after four in the afternoon,
>just evaluate
>
>    >> (4 + 12 + 13) // 24
>    == 5
>
>that is, 4 (o'clock) + 12 (i.e. PM) + 13 (elapsed time).
>
>BUT...  If I want to find out what hour is seventeen hours before
>three in the morning, I get a problem...
>
>    >> (3 - 17) // 24
>    == -14
>
>which ISN'T on the clock.  We can sidestep this ugliness by either
>
>1)  making sure that we never try to take a remainder with negative
>    arguments (which is the approach taken in dec2bin above), or
>
>2)  write a helper function that cleans up the positive/negative
>    mess, as follows
>
>        mod: func [
>            "computes true (positive) modulus"
>            a [integer!] "dividend"
>            b [integer!] "divisor"
>        ][
>            a // b + b // b
>        ]
>
>which allows us to see that
>
>    >> mod -5 2
>    == 1
>    >> mod -5 3
>    == 1
>
>and solve the time problems above
>
>    >> mod (4 + 12 + 13) 24
>    == 5
>    >> mod (3 - 17) 24
>    == 10
>
>Have fun!
>
>

Reply via email to