Wrong-but-not-incorrect code

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Rob Thorpe

    #16
    Re: Wrong-but-not-incorrect code

    dj3vande@csclub .uwaterloo.ca (Dave Vandervies) wrote in message news:<d1cv00$hu f$1@rumours.uwa terloo.ca>...[color=blue]
    > Seen in a chunk of code I was looking at recently (not mine!):
    > --------
    > char* imgfilename[100];
    > sprintf((char*) imgfilename, "mask%d.dib ", params.profile) ;
    > ReadImage((char *)imgfilename);
    > --------
    > (ReadImage is another part of the program's code that does exactly what
    > the reasonable reader would expect.)
    >
    > For the CLC readers:
    > Can you, by artifical construction or actual experience, come up with
    > something that's more Wrong and yet still manages to be correct code
    > that performs the intended task?
    >
    >
    > dave[/color]

    There is some particularly contorted code in the message cracker
    header windowsx.h in MS Windows that works. For instance:-

    #define HANDLE_WM_INITD IALOG(hwnd, wParam, lParam, fn) \
    (LRESULT)(DWORD )(UINT)(BOOL)(f n)((hwnd), (HWND)(wParam), lParam)

    Not that this is totally wrongheaded unlike the code you mentioned
    above. It's just mildly derranged.

    It's difficult looking at pieces of code like that you posted.
    Sometimes pieces work, but are bad style, others work but are
    undefined behaviour, still others are bugs but just happen to work.
    When code is contorted it's very hard to tell which is which.

    Comment

    • Richard Tobin

      #17
      Re: Wrong-but-not-incorrect code

      In article <87is3pyo7b.fsf @benpfaff.org>,
      Ben Pfaff <blp@cs.stanfor d.edu> wrote:
      [color=blue][color=green][color=darkred]
      >>> #define HASHSIZE 51 /* a small prime */[/color][/color][/color]
      [color=blue][color=green]
      >> The writer clearly didn't play enough card games.[/color][/color]
      [color=blue]
      >Are there many card games that call for a deck one card short?[/color]

      When you deal a pack of 52 cards between three players, you have one
      left over.

      -- Richard

      Comment

      • Chris Dollin

        #18
        Re: Wrong-but-not-incorrect code

        Ben Pfaff wrote:
        [color=blue]
        > Chris Dollin <kers@hpl.hp.co m> writes:
        >[color=green]
        >> Eric Sosman wrote:[color=darkred]
        >>> My personal favorite is this one-liner a colleague
        >>> found many years ago:
        >>>
        >>> #define HASHSIZE 51 /* a small prime */[/color]
        >>
        >> The writer clearly didn't play enough card games.[/color]
        >
        > Are there many card games that call for a deck one card short?[/color]

        I don't know about "many", but there are several three-handed games
        where all-but-one of the cards are dealt out, leaving the players
        with 17 each. The left-over card may be left concealed, or it may
        be exposed, or may be exchanged; it may determine the trump suit.

        The two that immediately come to mind are Black Maria aka Hearts,
        and Nullos. (Stares into space.) And Ninety-Nine.

        --
        Chris "electric hedgehog" Dollin

        Comment

        • Tor Rustad

          #19
          Re: Wrong-but-not-incorrect code

          "Dave Vandervies" <dj3vande@csclu b.uwaterloo.ca> wrote in message
          news:d1cv00$huf $1@rumours.uwat erloo.ca...[color=blue]
          > Seen in a chunk of code I was looking at recently (not mine!):
          > --------
          > char* imgfilename[100];
          > sprintf((char*) imgfilename, "mask%d.dib ", params.profile) ;
          > ReadImage((char *)imgfilename);
          > --------
          > (ReadImage is another part of the program's code that does exactly[/color]
          what[color=blue]
          > the reasonable reader would expect.)
          >
          > For the CLC readers:
          > Can you, by artifical construction or actual experience, come up with
          > something that's more Wrong and yet still manages to be correct code
          > that performs the intended task?[/color]

          Did a code audit once, of a program that had passed the integration
          testing phase. It was a 3000 liner in a single source file. Well, that
          happens... after scanning through +200 lines of globals.. I finally came
          to the main.. puuuh!

          The main() function was a +1500 liner, full of duplicate and
          complicated rollback code....

          Oh no... this wasn't any student code, the programmer had a CS
          master degree and multiple years of C/C++ programming
          experience. He had spent 3 months on this module. <g>

          --
          Tor <torust AT online DOT no>

          Comment

          • CBFalconer

            #20
            Re: Wrong-but-not-incorrect code

            Ben Pfaff wrote:[color=blue]
            > Chris Dollin <kers@hpl.hp.co m> writes:[color=green]
            > > Eric Sosman wrote:[/color]
            >[color=green][color=darkred]
            >>> My personal favorite is this one-liner a colleague
            >>> found many years ago:
            >>>
            >>> #define HASHSIZE 51 /* a small prime */[/color]
            >>
            >> The writer clearly didn't play enough card games.[/color]
            >
            > Are there many card games that call for a deck one card short?[/color]

            When one player keeps an Ace up his sleeve, yes.

            --
            "If you want to post a followup via groups.google.c om, don't use
            the broken "Reply" link at the bottom of the article. Click on
            "show options" at the top of the article, then click on the
            "Reply" at the bottom of the article headers." - Keith Thompson


            Comment

            • Chris Croughton

              #21
              Re: Wrong-but-not-incorrect code

              On Fri, 18 Mar 2005 16:26:33 +0000, Chris Dollin
              <kers@hpl.hp.co m> wrote:
              [color=blue]
              > Ben Pfaff wrote:
              >[color=green]
              >> Chris Dollin <kers@hpl.hp.co m> writes:
              >>[color=darkred]
              >>> Eric Sosman wrote:
              >>>> My personal favorite is this one-liner a colleague
              >>>> found many years ago:
              >>>>
              >>>> #define HASHSIZE 51 /* a small prime */
              >>>
              >>> The writer clearly didn't play enough card games.[/color]
              >>
              >> Are there many card games that call for a deck one card short?[/color]
              >
              > I don't know about "many", but there are several three-handed games
              > where all-but-one of the cards are dealt out, leaving the players
              > with 17 each. The left-over card may be left concealed, or it may
              > be exposed, or may be exchanged; it may determine the trump suit.
              >
              > The two that immediately come to mind are Black Maria aka Hearts,[/color]

              One of a number of games by both names, some are four-hand (the 'Hearts'
              program distributed with Windows is one of the latter, but I first
              played the same game four-handed some 30 years ago using the name "Black
              Maria").
              [color=blue]
              > and Nullos. (Stares into space.) And Ninety-Nine.[/color]

              There's also at least a couple where 16 cards are dealt to each player,
              with 4 being left to exchange.

              I've also played a three-hand version of Whist with the remaining card
              being used to determine which suit was trumps. That was 30-odd years
              ago as well (it was in a card games book which was at least 20 years
              older than that)...

              Chris C

              Comment

              • John Temples

                #22
                Re: Wrong-but-not-incorrect code

                In article <d1cv00$huf$1@r umours.uwaterlo o.ca>, Dave Vandervies wrote:[color=blue]
                > For the CLC readers:
                > Can you, by artifical construction or actual experience, come up with
                > something that's more Wrong and yet still manages to be correct code
                > that performs the intended task?[/color]

                I once had a do loop:

                do {
                /* stuff */
                } while (condition);

                that I later decided needed to be a for loop. So I just edited the
                top of the loop, forgetting about the bottom:

                for (i = 42; condition; i++) {
                /* stuff */
                } while (condition);

                When I later noticed what I had done, but that the code was still
                working correctly, I first thought that the compiler had not noticed a
                syntax error.

                --
                John W. Temples, III

                Comment

                • Keith Thompson

                  #23
                  Re: Wrong-but-not-incorrect code

                  Chris Croughton <chris@keristor .net> writes:[color=blue]
                  > On Fri, 18 Mar 2005 02:44:41 GMT, CBFalconer
                  > <cbfalconer@yah oo.com> wrote:
                  >[color=green]
                  >> Eric Sosman wrote:[color=darkred]
                  >>>[/color]
                  >> ... snip ...[color=darkred]
                  >>>
                  >>> My personal favorite is this one-liner a colleague
                  >>> found many years ago:
                  >>>
                  >>> #define HASHSIZE 51 /* a small prime */[/color]
                  >>
                  >> A few years ago, in this very newsgroup, 91 enjoyed similar fame.[/color]
                  >
                  > With a bit more reasonableness, since 13*7 is harder to recognise as
                  > non-prime than 3*17...[/color]

                  Sure, but there's a trick for multiples of 7 as well. Take the last
                  digit, double it, and subtract from what's left. Iterate as needed.
                  If the final result is 0 or 7, it's a multiple of 7; if not, not.

                  9 - (2*1) == 7

                  (Unlike the multiples-of-3 and multiples-of-9 tricks, it doesn't tell
                  you the remainder for non-multiples.)

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                  San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                  We must do something. This is something. Therefore, we must do this.

                  Comment

                  • Chris Croughton

                    #24
                    Re: Wrong-but-not-incorrect code

                    On Fri, 18 Mar 2005 19:53:46 GMT, Keith Thompson
                    <kst-u@mib.org> wrote:
                    [color=blue]
                    > Chris Croughton <chris@keristor .net> writes:[color=green]
                    >> On Fri, 18 Mar 2005 02:44:41 GMT, CBFalconer
                    >> <cbfalconer@yah oo.com> wrote:
                    >>[color=darkred]
                    >>> Eric Sosman wrote:
                    >>>>
                    >>> ... snip ...
                    >>>>
                    >>>> My personal favorite is this one-liner a colleague
                    >>>> found many years ago:
                    >>>>
                    >>>> #define HASHSIZE 51 /* a small prime */
                    >>>
                    >>> A few years ago, in this very newsgroup, 91 enjoyed similar fame.[/color]
                    >>
                    >> With a bit more reasonableness, since 13*7 is harder to recognise as
                    >> non-prime than 3*17...[/color]
                    >
                    > Sure, but there's a trick for multiples of 7 as well. Take the last
                    > digit, double it, and subtract from what's left. Iterate as needed.
                    > If the final result is 0 or 7, it's a multiple of 7; if not, not.
                    >
                    > 9 - (2*1) == 7[/color]

                    I've never heard of that one! What do you do with small numbers with
                    large digits on the right, though? It looks as though perhaps you just
                    ignore the sign (14 => 1 - 4*2 = -7, 35 => 3 - 5*2 = -7, 49 => 4 - 9*2 =
                    -14 => 14 as above...). I don't see how it works...
                    [color=blue]
                    > (Unlike the multiples-of-3 and multiples-of-9 tricks, it doesn't tell
                    > you the remainder for non-multiples.)[/color]

                    True. OK, what about multiples of 13 and 17? <g>)

                    Chris C

                    Comment

                    • CBFalconer

                      #25
                      Re: Wrong-but-not-incorrect code

                      Keith Thompson wrote:[color=blue]
                      >[/color]
                      .... snip ...[color=blue]
                      >
                      > Sure, but there's a trick for multiples of 7 as well. Take the last
                      > digit, double it, and subtract from what's left. Iterate as needed.
                      > If the final result is 0 or 7, it's a multiple of 7; if not, not.
                      >
                      > 9 - (2*1) == 7
                      >
                      > (Unlike the multiples-of-3 and multiples-of-9 tricks, it doesn't tell
                      > you the remainder for non-multiples.)[/color]

                      How does that work when you run into negative values. Ex: 427

                      42 - 2*7 = 28
                      2 - 2*8 = ???

                      and why?

                      --
                      "If you want to post a followup via groups.google.c om, don't use
                      the broken "Reply" link at the bottom of the article. Click on
                      "show options" at the top of the article, then click on the
                      "Reply" at the bottom of the article headers." - Keith Thompson


                      Comment

                      • CBFalconer

                        #26
                        Re: Wrong-but-not-incorrect code

                        John Temples wrote:[color=blue]
                        > Dave Vandervies wrote:
                        >[color=green]
                        >> Can you, by artifical construction or actual experience, come up
                        >> with something that's more Wrong and yet still manages to be
                        >> correct code that performs the intended task?[/color]
                        >
                        > I once had a do loop:
                        >
                        > do {
                        > /* stuff */
                        > } while (condition);
                        >
                        > that I later decided needed to be a for loop. So I just edited
                        > the top of the loop, forgetting about the bottom:
                        >
                        > for (i = 42; condition; i++) {
                        > /* stuff */
                        > } while (condition);
                        >
                        > When I later noticed what I had done, but that the code was still
                        > working correctly, I first thought that the compiler had not
                        > noticed a syntax error.[/color]

                        Yes, that does take at least a second look to see the effect. I
                        gather you had no urge to alter 'condition' at the same time.

                        --
                        "If you want to post a followup via groups.google.c om, don't use
                        the broken "Reply" link at the bottom of the article. Click on
                        "show options" at the top of the article, then click on the
                        "Reply" at the bottom of the article headers." - Keith Thompson


                        Comment

                        • Martin Ambuhl

                          #27
                          Re: Wrong-but-not-incorrect code

                          Keith Thompson wrote:[color=blue]
                          > Chris Croughton <chris@keristor .net> writes:[/color]
                          [color=blue]
                          > Sure, but there's a trick for multiples of 7 as well. Take the last
                          > digit, double it, and subtract from what's left. Iterate as needed.
                          > If the final result is 0 or 7, it's a multiple of 7; if not, not.
                          >
                          > 9 - (2*1) == 7
                          >
                          > (Unlike the multiples-of-3 and multiples-of-9 tricks, it doesn't tell
                          > you the remainder for non-multiples.)[/color]

                          There are similar tricks with a multiplier of 5 (for divisibility by 17)
                          ot 5 (divisibility by 13), but negative numbers are frequent.

                          Comment

                          • Keith Thompson

                            #28
                            Re: Wrong-but-not-incorrect code

                            CBFalconer <cbfalconer@yah oo.com> writes:[color=blue]
                            > Keith Thompson wrote:[color=green]
                            >>[/color]
                            > ... snip ...[color=green]
                            >>
                            >> Sure, but there's a trick for multiples of 7 as well. Take the last
                            >> digit, double it, and subtract from what's left. Iterate as needed.
                            >> If the final result is 0 or 7, it's a multiple of 7; if not, not.
                            >>
                            >> 9 - (2*1) == 7
                            >>
                            >> (Unlike the multiples-of-3 and multiples-of-9 tricks, it doesn't tell
                            >> you the remainder for non-multiples.)[/color]
                            >
                            > How does that work when you run into negative values. Ex: 427
                            >
                            > 42 - 2*7 = 28
                            > 2 - 2*8 = ???
                            >
                            > and why?[/color]

                            2 - 2*8 = -14, which is a multiple of 7, so 28 is a multiple of 7, so
                            427 is a multiple of 7. (I mis-stated the condition before; I forgot
                            that the result can be negative.)

                            If you happen to know that 42 is a multiple of 7, you can omit the
                            final step.

                            --
                            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                            San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                            We must do something. This is something. Therefore, we must do this.

                            Comment

                            • Chris Croughton

                              #29
                              Re: Wrong-but-not-incorrect code

                              On Fri, 18 Mar 2005 21:29:07 GMT, CBFalconer
                              <cbfalconer@yah oo.com> wrote:
                              [color=blue]
                              > Keith Thompson wrote:[color=green]
                              >>[/color]
                              > ... snip ...[color=green]
                              >>
                              >> Sure, but there's a trick for multiples of 7 as well. Take the last
                              >> digit, double it, and subtract from what's left. Iterate as needed.
                              >> If the final result is 0 or 7, it's a multiple of 7; if not, not.
                              >>
                              >> 9 - (2*1) == 7
                              >>
                              >> (Unlike the multiples-of-3 and multiples-of-9 tricks, it doesn't tell
                              >> you the remainder for non-multiples.)[/color]
                              >
                              > How does that work when you run into negative values. Ex: 427
                              >
                              > 42 - 2*7 = 28
                              > 2 - 2*8 = ???[/color]

                              2 - 2*8 = -14, so ignore the sign and continue:

                              1 - 2*4 = -7, ignore the sign and it's a multiple of 7.
                              [color=blue]
                              > and why?[/color]

                              That's what puzzles me. It does work, it seems, but I don't understand
                              it...

                              Chris C

                              Comment

                              • Michael Wojcik

                                #30
                                Re: Wrong-but-not-incorrect code


                                In article <slrnd3of3v.d79 .chris@ccserver .keris.net>, Chris Croughton <chris@keristor .net> writes:[color=blue][color=green]
                                > > Keith Thompson wrote:[color=darkred]
                                > >>
                                > >> Sure, but there's a trick for multiples of 7 as well. Take the last
                                > >> digit, double it, and subtract from what's left. Iterate as needed.
                                > >> If the final result is 0 or 7, it's a multiple of 7; if not, not.[/color][/color]
                                >
                                > That's what puzzles me. It does work, it seems, but I don't understand
                                > it...[/color]

                                Let's see. It's easy to prove it works for the case where N/10 is
                                a multiple of 7, just by considering three cases: the one's digit is
                                0, 2*0 is 0, and you're left with N/10; the one's digit is 7, you
                                subtract a multiple of 7 from another multiple of 7, and their
                                difference must then also be a multiple of 7; or anything else (you
                                subtract a non-multiple of 7 from a multiple of 7, their difference
                                cannot be a multiple of 7).

                                The cases where N/10 is not a multiple of 7 are a bit trickier, but
                                not that much.

                                Consider the two-digit case:

                                N has digits a and b, so N == 10*a + b.

                                Hypothesis: 10*a + b == 0 (mod 7) iff a - 2*b == 0 (mod 7). (Note
                                that the case where you're left with 7 as the sole remaining digit is
                                just the other case, in base 10, of 0 mod 7 as a single digit.)

                                Now, this is the same as saying that a mod 7 == 2*b mod 7, so that
                                when we subtract 2*b from a, we cancel out the noncongruency to 0 (I
                                think - I am most definitely not a mathematician). In other words,
                                if a is, say, 3 "away" from a multiple of 7, then 2*b also must be 3
                                "away" from a multiple of 7.

                                Now think about a mod 7. This is the penultimate remainder you'd
                                have if you were dividing 7 into a number using long division. To
                                have a 0 remainder for the whole division process, ten times that
                                penultimate remainder (ie 10*(a mod 7)) plus the final digit (b) must
                                be a multiple of 7. If a mod 7 == 2, then b must be 1 or 8, for
                                example.

                                Equivalently, whatever 10*a is congruent to mod 7, b must be
                                congruent to 7 minus that value. If 10*a == 0 (mod 7), b must also
                                == 0 (mod 7); if 10*a == 1, b == 6, and so forth.

                                Make a table comparing a mod 7 with 10a mod 7. If 10a mod 7 is 1, a
                                mod 7 will be 3 (eg 10 mod 7 == 3, 80 mod 7 == 3, etc). So we want
                                the mapping between b mod 7 (must equal 10a mod 7) to 2b mod 7 (must
                                equal a mod 7) to be the converse of that between 10a and a. If
                                going from 10a to a gives us 1, going from b to 2b must give us 6,
                                and so forth:

                                And it is. If 10a is 1, a is 5; if b is 1, 2b is 2. 5 + 2 == 0.
                                And so on, for 0 through 6. You can write out the tables (of
                                congruencies mod 7):

                                10a | a b | 2b a + 2b
                                -------- ------- ------
                                0 | 0 0 | 0 0+0=0
                                1 | 5 1 | 2 5+2=0
                                2 | 3 2 | 4 3+4=0
                                3 | 1 3 | 6 1+6=0
                                4 | 6 4 | 1 6+1=0
                                5 | 4 5 | 3 4+3=0
                                6 | 2 6 | 5 2+5=0

                                (What's the term for the relationship between a and 2b in this case?
                                I can't remember.)

                                And I think that's why it works.

                                --
                                Michael Wojcik michael.wojcik@ microfocus.com

                                _
                                | 1
                                | _______ d(cabin) = log cabin + c = houseboat
                                | (cabin)
                                _| -- Thomas Pynchon

                                Comment

                                Working...