Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

Decimal to Binary Script

 [1/6] from: ptretter::charter::net at: 1-Aug-2000 7:48

Ok, I created my first useful function. 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 ]

 [2/6] from: joel:neely:fedex at: 1-Aug-2000 10:51

[ptretter--charter--net] 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
<<quoted lines omitted: 12>>
> 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
>> dec-to-bin -10
>> 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!

 [3/6] from: tim:johnsons-web at: 1-Aug-2000 7:56

That's cool Paul. BTW: If you check out the user's guide, you'll see the function print-binary in the section on logical operators. It does the same thing, but I as a relative newbie find yours more readable. Might be fun to compare benchmarks. hmmm! -Tim At 07:48 AM 8/1/00 -0500, you wrote:

 [4/6] from: ptretter:charter at: 1-Aug-2000 11:18

This is excellent stuff and I will be absorbing everything you have done. I knew it didnt correctly handle negative integers and I also knew that it would clobber "holder". Your suggestions are excellent and I appreciate your comments. I originally made this to supplement a Subnet Calculator that I was working on which my function was sufficient. I like your modifications and explaination. Thanks for all the feedback. Paul Tretter

 [5/6] from: ptretter:charter at: 1-Aug-2000 11:19

I believe the one your referring to used the enbase function which is limited in handling "0-255" to binary.

 [6/6] from: tim:johnsons-web at: 1-Aug-2000 9:07

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:

  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted