Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Wrong-but-not-incorrect code

Reply
Thread Tools

Wrong-but-not-incorrect code

 
 
CBFalconer
Guest
Posts: n/a
 
      03-18-2005
Ben Pfaff wrote:
> Chris Dollin <> writes:
> > 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.

>
> Are there many card games that call for a deck one card short?


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

--
"If you want to post a followup via groups.google.com, 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


 
Reply With Quote
 
 
 
 
John Temples
Guest
Posts: n/a
 
      03-18-2005
In article <d1cv00$huf$>, Dave Vandervies wrote:
> 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?


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
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      03-18-2005
Chris Croughton <> writes:
> On Fri, 18 Mar 2005 02:44:41 GMT, CBFalconer
> <> wrote:
>
>> 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.

>
> With a bit more reasonableness, since 13*7 is harder to recognise as
> non-prime than 3*17...


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_Keith) kst- <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.
 
Reply With Quote
 
Chris Croughton
Guest
Posts: n/a
 
      03-18-2005
On Fri, 18 Mar 2005 19:53:46 GMT, Keith Thompson
<kst-> wrote:

> Chris Croughton <> writes:
>> On Fri, 18 Mar 2005 02:44:41 GMT, CBFalconer
>> <> wrote:
>>
>>> 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.

>>
>> With a bit more reasonableness, since 13*7 is harder to recognise as
>> non-prime than 3*17...

>
> 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


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...

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


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

Chris C
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      03-18-2005
Keith Thompson wrote:
>

.... snip ...
>
> 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.)


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.com, 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


 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      03-18-2005
John Temples wrote:
> Dave Vandervies wrote:
>
>> 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?

>
> 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.


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.com, 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


 
Reply With Quote
 
Martin Ambuhl
Guest
Posts: n/a
 
      03-18-2005
Keith Thompson wrote:
> Chris Croughton <> writes:


> 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.)


There are similar tricks with a multiplier of 5 (for divisibility by 17)
ot 5 (divisibility by 13), but negative numbers are frequent.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-18-2005
CBFalconer <> writes:
> Keith Thompson wrote:
>>

> ... snip ...
>>
>> 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.)

>
> How does that work when you run into negative values. Ex: 427
>
> 42 - 2*7 = 28
> 2 - 2*8 = ???
>
> and why?


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_Keith) kst- <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.
 
Reply With Quote
 
Chris Croughton
Guest
Posts: n/a
 
      03-19-2005
On Fri, 18 Mar 2005 21:29:07 GMT, CBFalconer
<> wrote:

> Keith Thompson wrote:
>>

> ... snip ...
>>
>> 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.)

>
> How does that work when you run into negative values. Ex: 427
>
> 42 - 2*7 = 28
> 2 - 2*8 = ???


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

1 - 2*4 = -7, ignore the sign and it's a multiple of 7.

> and why?


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

Chris C
 
Reply With Quote
 
Michael Wojcik
Guest
Posts: n/a
 
      03-20-2005

In article <>, Chris Croughton <> writes:
> > Keith Thompson wrote:
> >>
> >> 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.

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


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

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

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
what is the difference between code inside a <script> tag and code in the code-behind file? keithb ASP .Net 1 03-29-2006 01:00 AM
Fire Code behind code AND Javascript code associated to a Button Click Event =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?= ASP .Net 4 02-11-2004 07:31 AM
Re: Code Behind vs. no code behind: error Ben Miller [msft] ASP .Net 1 06-28-2003 01:46 AM
Re: C# Equivalent of VB.Net Code -- One line of code, simple Ian ASP .Net 0 06-25-2003 01:14 PM
Re: C# Equivalent of VB.Net Code -- One line of code, simple Ron ASP .Net 1 06-24-2003 07:18 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57