• LCrawford (unregistered)

    Ahh yes, the 70's and the feeling of being the frist developer to encounter these coding situations. The ultimate Not Invented Here library of routines.

  • Prime Mover (unregistered)

    Bitwise or no bitwise, not sure whether exponentiation could ever be the way to go here. Exponentiation can be expensive. Because I don't have the manual in front of me (Bob bogarted it), I can't check this, but I wouldn't risk implementing something which may compromise response time.

  • (nodebb)

    Bits wise, byte foolish!

  • S's cat (unregistered)

    Doesn't BITON have a bug? If A is out of range it sets the value as false, but then falls through to the IF statement with C undefined.

  • akozakie (unregistered)

    Say what you want, but I'd LOVE to support this. So what if the implementation sucks. It works, it's clear and readable, intent is obvious... incredibly easy to fix or optimize anything as needed. Give me that over any "mostly correct, fast and efficient code" with a mix of premature optimization and stack overflow ^C^V, with no comments, nonexistent documentation, no consistency in names and "only some seemingly trivial bugs"...

  • Anon E. Mouse (unregistered)

    The really funny (smell, not ha ha) thing is that the ACM had an entire referred journal devoted to these things. You could go back to the early volumes (have to love open stack libraries) and find proven algos for this kind of stuff. Or you could go to Knuth's 3 volume set.

    The one thing you didn't do was hand code it blind. As a EE/CS student in the late 70s/early 80s, my Profs would have - rightfully - roasted me for this. If you could cite a source, it was OK. But off the cuff. Nope.

  • Hasseman (unregistered)

    HP3000. Software created 1972 was guaranteed to still work 2010. Maybe not the sexiest machines but very stable. We had 380 days of uptime once. HP3000, Vax11/750 and DataGeneral Eclipse. Good old days.

  • Duston (unregistered)

    I learned BASIC on an HP3000 (1978). My fond memory was that it didn't have subscripted strings, so a subroutine to sort a bunch of strings alphabetically was for the advanced students. And the other fond memory was that most of the terminals used acoustically coupled modems, so if you stood up too quickly and made your chair squeak, you'd knock a room full of terminals off line. Good times.

  • The incredible Holk (unregistered)

    Move those repeated case blocks to a separate function and the code becomes almost sane.

  • (nodebb) in reply to S's cat

    Yeah, buggy. If A doesn't match, C will be uninitialized which means it's an unpredictable value. In TIO, the uninitialized value of C depended on the last run:

    uninitialized first: random value in C, resulted in TRUE result: https://tio.run/##K0gsTk7M0U0rSP7/Pyk1PTOPi7O8KLMkVUPdIzUnJ19HITy/KCdFUV3Tmis1L0Xv/38A

    intialized first: zero in C, resulted in runtime error: https://tio.run/##K0gsTk7M0U0rSP7/Pyk1PTOPi7O8KLMkVUPdIzUnJ19HITy/KCdFUV3Tmis1L0Xv/38A

  • Couple Things (unregistered)

    Change all the INTEGER types to WORD and you'll actually have code that works.

    ... ok just the one thing.

  • The other thing (unregistered)

    Remembered the other thing: I don't like that the MSB is referenced as bit 0.

  • Zygo (unregistered)

    Exponentiation in the 70's was amazingly expensive, even when not counting the floating-point-to-int type conversions needed.

    So of course we would precompute that in a table to look up at run time.

    Oh. Right.

    For the '90s EE/CS student, off the cuff stuff was OK, you'd "only" have to give a correctness proof to justify it. A reference to someone else's published proof then becomes valuable to save work.

    It's amazing how much code we rely on every day is based on someone's grad thesis paper.

  • Randal L. Schwartz (google)

    My first substantial coding was on the predecessor to the 3000, the HP2000, in TimeShare Basic. The 2000 was actually a pair of HP2100 machines: one for I/O and one for core compute. Dialup 110 baud ASR-33 uppercase-only TTY, with paper-tape storage. Sat in the "computer closet" for many hours a day during my Junior high and high school years. Probably why I have a ringing in my ears now.

  • Bart (unregistered) in reply to Prime Mover

    It's very unlikely that this version of Pascal supported integer exponentiation out of the box. It would possibly have an exp() function, using reals.

  • The Shadow Knows (unregistered)

    "Giant" case statements?

  • (nodebb)

    Could it be that at the time the code was written, or the system it was written on, or another system it might have to run on, didn't support bitwise operators? That's the most likely explanation.

  • (nodebb) in reply to The incredible Holk

    Move those repeated case blocks to a separate function and the code becomes almost sane.

    I'm thinking an array containing the required power of two and indexed by the bit number.

    Addendum 2021-09-15 05:14: It reminds me of a Stack Overflow question "what's the fastest way to calculate the nth Fibonacci number". My answer was to put the first 96 in an array (assuming the required answer is returned as a 64 bit int) and just do a look up.

  • (nodebb)

    The thing that really weirds me out is the choice of ordering the bits left-to-right, rather than by power of two like pretty much everyone does.

  • Foo AKA Fooo (unregistered)

    So we're not commenting on turning an O(1) operation into O(n^2) (LAND)? Sure, one order of magnitude is par for submissions here, but two?

    Or the unnecessary SETBITON call when BITON is already true?

    Using a REPEAT loop instead of FOR? (So much for readability?)

    The good old "IF .. THEN ... True ELSE ... False" pattern?

    At least the "OTHERWISE" bug in BITON (which stems from Pascal not having a RETURN statement) has been mentioned, as well as a problem with the high bit (assuming INTEGER is 16 bit). (WORD is not a standard Pascal type; if this compiler doesn't have it, the high bit needs special cases, depending on whether it's two's complement or other representation, which are considerations you normally don't want to see in Pascal code.)

    No, sorry, there's nothing good about this code.

  • (nodebb) in reply to Medinoc

    The HP3000 was a big-endian machine. So the sign bit was bit 0. and the address of an integer was the address of its most significant byte (assuming it had byte-addressable memory) Like the Motorola 68000s. Like the Sun Sparc. Like the fundamental networking protocols.

  • (nodebb)

    NOT even close... DEC minicomputers had multiple timesharing operating systems release in 1968 (and pre-release was avail a bit earlier)

  • The Shadow Knows (unregistered) in reply to Jeremy Pereira

    Reminds me of a test question at an interview long ago - basically write a program that prints the result of [complex equation] and my solution was something like PRINT 1234546. I'd mentally solved the equation and was ready to argue that they needed to have better specs for their assignments.

  • Stan Sieler (unregistered)

    I'll comment on the Pascal example and: "One thing I appreciate about Pascal code is that, [...] it's incredibly readable. "

    If you're saying that "biton" is "incredibly readable", well ... No... it's fairly readable. It could be much much more readable:

    <see code in next comment, due to comment size limitations, sigh>

    The above shows a number of topics that are in my book, "The Real Art of Computer Programming":

    • variable names matter (and parameter names).

    • function names matter.
      ("biton" isn't clear...a reader of code elsewhere might think that it turns a bit on, rather than tests if a bit is on)

    • bounds checking matters . (the original "otherwise" would return a misleading result when called with an out-of-bounds bit number)

    • simpler (less) indentation makes things more readable.

    • commenting the end of a function makes it easier to find in an editor.

    • comments documenting the purpose(and assumptions) of the function are important.

    ...but that's what shows the art of programming, versus the "get something working".

    Note that every one of those topics apply to Python, Rust, Java, Javascript, C++, Sharp, as well as C, COBOL, BASIC, FORTRAN, APL, SPL, SPLash!, and Pascal.

    Also, one commentator mentioned using exponentiation...

    A quick test using Pascal/iX on an HP 3000 (PA-RISC 32/64-bit computer), showed that the 'case' approach was about twice as fast as using exponentiation.

    Remember that exponentiation is not in the Pascal standard. And, if your variant has it (e.g.: "^" or "**"), it's probably not likely to have the extra code required to say "hey, mon, the value on the left is 2 ... I know how to do that quickly", so it's extremely likely to call a helper/library routine to do the exponentiation. (Speaking as a compiler author here :)

    Stan Sieler [email protected]

  • Stan Sieler (unregistered)

    (The following assumes two simple utility routines: 'num64' (which converts an integer to the string representation, and 'abort', which aborts the program.)

    {==============================================================} function is_bit_on (val : integer; bitnum: integer) : boolean;

     {returns 'true' if the specified bit is on in val, else 'false'. }
     {Handles up to 16 bits, and assumes bit 15 is the low order bit, }
     {and bit 0 is the high order bit (most significant bit).         }
     {NOTE: assumes 'integer' is either 32 bits or larger, or if it is}
     {16 bits, that the compiler allows a constant of 32768.          }
    

    var power_of_two : integer; {will hold 2 ** bitnum}

    begin

    if (bitnum < 0) or (bitnum > 15) then abort ('OOPS: bitnum = ' + num64 (bitnum));

    case bitnum of 0: power_of_two := 32768; 1: power_of_two := 16384; 2: power_of_two := 8192; 3: power_of_two := 4096; 4: power_of_two := 2048; 5: power_of_two := 1024; 6: power_of_two := 512; 7: power_of_two := 256; 8: power_of_two := 128; 9: power_of_two := 64; 10: power_of_two := 32; 11: power_of_two := 16; 12: power_of_two := 8; 13: power_of_two := 4; 14: power_of_two := 2; 15: power_of_two := 1; end;

    if ((val div power_of_two) mod 2) = 1 then is_bit_on := true

    else is_bit_on := false;

    end {is_bit_on proc}; {==============================================================}

  • Arto Ahlstedt (unregistered)

    I needed byte-wide XOR and had to resort to building a (very straightforward so it was 15 min study and worked on first try) SPL (HP 3000's Systems Programming Language) function and link my Pascal program to it. So, the thing even had a low-level somewhat structured language!

Leave a comment on “Wise About Bits”

Log In or post as a guest

Replying to comment #:

« Return to Article