449,079 Members | 880 Online
Need help? Post your question and get tips & solutions from a community of 449,079 IT Pros & Developers. It's quick & easy.

# C bit twidders ... I'm in need of a dose of clever.

 P: n/a The purpose is for a shellsort. I am experimenting with the increment for shellsort using a modified version of Pete's driver and this bit of code (shell_ratio is a floating point number for the time being during my search): void ssort2b(e_type array[], size_t count) { size_t i, inc, j; e_type tmp; int inversion = 1.0 / shell_ratio; for (inc = count; inc 0;) { for (i = inc; i < count; i++) { j = i; tmp = array[i]; while (j >= inc && (GT(array + j - inc, &tmp))) { array[j] = array[j - inc]; j -= inc; } array[j] = tmp; } if (inc <= inversion && inc 1) { inc = 1; } else inc *= shell_ratio; } } At any rate, the bit at the end with: if (inc <= inversion && inc 1) { inc = 1; } else inc *= shell_ratio; really gives me the heebie-jeebies (imagining missed branch predictions). Eventually, I am going to use a rational increment and I also would like to change the calculation for the last increment so it is totally branchless. So what I am wondering is: "Is there a way to modify an integer so that there is no change if it is larger to a certain value and so that it gets truncated to 1 if it is less than or equal to a certain value?" It also needs to get clobbered on the final pass so that it becomes zero, so the bitwise operations would also have to take that into account. Jan 30 '07 #1
24 Replies

 P: n/a On Tue, 30 Jan 2007, user923005 wrote: At any rate, the bit at the end with: if (inc <= inversion && inc 1) { inc = 1; } else inc *= shell_ratio; really gives me the heebie-jeebies (imagining missed branch predictions). Eventually, I am going to use a rational increment and I also would like to change the calculation for the last increment so it is totally branchless. Before trying to optimize, please make sure that that piece of code is the one which is really eating up most of the time. You should use a profiling tool for doing these timing measurements (e.g. vTune from Intel for Windows or Linux on x86, or Quantify from Rational/IBM for other UNIX platforms). Otherwise you will be surprised that despite your optimization efforts you gain nothing. Detecting the "hotspots" in a piece of code (i.e. the parts which eat up most of the time) can be an experience full of surprises ;-) So what I am wondering is: "Is there a way to modify an integer so that there is no change if it is larger to a certain value and so that it gets truncated to 1 if it is less than or equal to a certain value?" Well, I'm not sure I have understood correctly your question. I think you want to rewite the above piece of code without using "if" statements. You can use the conditional operator ("?:") or exploit the fact that in C logical expressions, such as "inc <= inversion && inc 1" yield an integer value of 1 if their logical value is "true" and 0 otherwise. With a little bit of simple arithmetics you can construct an expression that replaces the "if" statement, for example: int x; .. .. if () x = a; else x = b; can be rewritten as: int cond; .. .. .. cond = ; x = cond * a + !cond * b; The reason for using the intermedirate "cond" variable to make sure that

 P: n/a On Jan 30, 3:43 am, Kohn Emil Dan At any rate, the bit at the end with: if (inc <= inversion && inc 1) { inc = 1; } else inc *= shell_ratio; really gives me the heebie-jeebies (imagining missed branch predictions). Eventually, I am going to use a rational increment and I also would like to change the calculation for the last increment so it is totally branchless. Before trying to optimize, please make sure that that piece of code is the one which is really eating up most of the time. You should use a profiling tool for doing these timing measurements (e.g. vTune from Intel for Windows or Linux on x86, or Quantify from Rational/IBM for other UNIX platforms). Otherwise you will be surprised that despite your optimization efforts you gain nothing. Detecting the "hotspots" in a piece of code (i.e. the parts which eat up most of the time) can be an experience full of surprises ;-) So what I am wondering is: "Is there a way to modify an integer so that there is no change if it is larger to a certain value and so that it gets truncated to 1 if it is less than or equal to a certain value?" Well, I'm not sure I have understood correctly your question. I think you want to rewite the above piece of code without using "if" statements. You can use the conditional operator ("?:") or exploit the fact that in C logical expressions, such as "inc <= inversion && inc 1" yield an integer value of 1 if their logical value is "true" and 0 otherwise. With a little bit of simple arithmetics you can construct an expression that replaces the "if" statement, for example: int x; . . if () x = a; else x = b; can be rewritten as: int cond; . . . cond = ; x = cond * a + !cond * b; The reason for using the intermedirate "cond" variable to make sure that

 P: n/a user923005 wrote: At any rate, the bit at the end with: if (inc <= inversion && inc 1) { inc = 1; } else inc *= shell_ratio; really gives me the heebie-jeebies (imagining missed branch predictions). Eventually, I am going to use a rational increment and I also would like to change the calculation for the last increment so it is totally branchless. /* BEGIN s_sort defines */ #define NUMERATOR 3 #define DENOMINATOR 7 #define OFFSET (DENOMINATOR - 2 * NUMERATOR) /* END s_sort defines */ inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; If numerator and denominator are 3 and 8, then you could have: inc = inc + inc + inc + 2 >3; -- pete Jan 30 '07 #4

 P: n/a On Jan 30, 12:56 pm, pete 3; -- pete I don't understand how it is supposed to work. I get the increment itself being affected, so obviously I am not using it right: #include /* BEGIN s_sort defines */ #define NUMERATOR 31023 #define DENOMINATOR 100000 #define OFFSET (DENOMINATOR - 2 * NUMERATOR) /* END s_sort defines */ int main(void) { size_t inc = 1000000, jnc = 1000000; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } inc = jnc = 10009711; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } return 0; } /* inc=9582,jnc=310230 inc=2973,jnc=96242 inc=922,jnc=29857 inc=286,jnc=9262 inc=89,jnc=2873 inc=27,jnc=891 inc=8,jnc=276 inc=2,jnc=85 inc=1,jnc=26 inc=0,jnc=8 inc=12936,jnc=3105312 inc=4013,jnc=963360 inc=1245,jnc=298863 inc=386,jnc=92716 inc=120,jnc=28763 inc=37,jnc=8923 inc=11,jnc=2768 inc=3,jnc=858 inc=1,jnc=266 inc=0,jnc=82 */ Jan 31 '07 #5

 P: n/a I probably just did not pose the problem clearly. Anyway, I came up with this solution: #include /* BEGIN s_sort defines */ #define NUMERATOR 31023 #define DENOMINATOR 100000 #define OFFSET (DENOMINATOR - 2 * NUMERATOR) /* END s_sort defines */ int main(void) { size_t inc = 1000000; double dinvert = DENOMINATOR * 1.0 / NUMERATOR; size_t stinvert = (size_t) dinvert; int danger_danger=0 ; while (inc 0) { inc *= 31023; inc /= 100000; inc += danger_danger; danger_danger = (inc <= stinvert && inc 1); printf("inc=%u\n", inc); } inc = 10009711; danger_danger=0 ; while (inc 0) { inc *= 31023; inc /= 100000; inc += danger_danger; danger_danger = (inc <= stinvert && inc 1); printf("inc=%u\n", inc); } return 0; } Jan 31 '07 #6

 P: n/a Aargh -- this solutions is broken also due to integer modular math. My increment is too large for 32 bit unsigned. Maybe I will have to use float. P.U. Jan 31 '07 #7

 P: n/a /* Here is what I ended up with: */ void dcss(e_type * array, size_t h) { e_type *i, *j, *k, *after, temp; static const float shell_ratio = 0.31023; size_t inversion = (size_t) (1.0f / shell_ratio); size_t danger_danger = 0; after = array + h; h *= shell_ratio; while (h != 0) { i = array + h; do { j = i - h; if (GT(j, i)) { k = i; temp = *k; do { *k = *j; k = j; if (h + array j) { break; } j -= h; } while (GT(j, &temp)); *k = temp; } ++i; } while (i != after); h *= shell_ratio; h += danger_danger; danger_danger = (h <= inversion && h 1); } } Jan 31 '07 #8

 P: n/a user923005 wrote: > On Jan 30, 12:56 pm, pete 3; -- pete I don't understand how it is supposed to work. I get the increment itself being affected, so obviously I am not using it right: #include /* BEGIN s_sort defines */ #define NUMERATOR 31023 #define DENOMINATOR 100000 #define OFFSET (DENOMINATOR - 2 * NUMERATOR) /* END s_sort defines */ int main(void) { size_t inc = 1000000, jnc = 1000000; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } inc = jnc = 10009711; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } return 0; } /* inc=9582,jnc=310230 inc=2973,jnc=96242 inc=922,jnc=29857 inc=286,jnc=9262 inc=89,jnc=2873 inc=27,jnc=891 inc=8,jnc=276 inc=2,jnc=85 inc=1,jnc=26 inc=0,jnc=8 inc=12936,jnc=3105312 inc=4013,jnc=963360 inc=1245,jnc=298863 inc=386,jnc=92716 inc=120,jnc=28763 inc=37,jnc=8923 inc=11,jnc=2768 inc=3,jnc=858 inc=1,jnc=266 inc=0,jnc=82 */ The increment algorithm has problems when (size_t)-1 / NUMERATOR - OFFSET nmemb is true and NUMERATOR is large. I haven't decided how large "large" means, but I think it's somewhere around ten or a hundred. If I reduce the initial values of inc: /* BEGIN new.c */ #include /* BEGIN s_sort defines */ #define NUMERATOR 31023 #define DENOMINATOR 100000 #define OFFSET (DENOMINATOR - 2 * NUMERATOR) /* END s_sort defines */ int main(void) { size_t inc = 100000, jnc = 100000; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } inc = jnc = 100097; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } return 0; } /* END new.c */ Then I get: inc=31023,jnc=31023 inc=9624,jnc=9624 inc=2986,jnc=2985 inc=926,jnc=926 inc=287,jnc=287 inc=89,jnc=89 inc=27,jnc=27 inc=8,jnc=8 inc=2,jnc=2 inc=1,jnc=0 inc=0,jnc=0 inc=31053,jnc=31053 inc=9633,jnc=9633 inc=2988,jnc=2988 inc=927,jnc=926 inc=287,jnc=287 inc=89,jnc=89 inc=27,jnc=27 inc=8,jnc=8 inc=2,jnc=2 inc=1,jnc=0 inc=0,jnc=0 To make the Shellsort work with large DENOMINATOR and large nmemb also, I had to hybridize the sorting function for an integer math part and a floating point part: void shsort(e_type *array, size_t nmemb) { e_type *i, *j, *k, *after, temp; after = array + nmemb; if (((size_t)-1 - OFFSET) / NUMERATOR nmemb) { nmemb = (nmemb * NUMERATOR + OFFSET) / DENOMINATOR; } else { nmemb *= (double)NUMERATOR / DENOMINATOR; } while (nmemb ((size_t)-1 - OFFSET) / NUMERATOR) { i = array + nmemb; do { j = i - nmemb; if (GT(j, i)) { k = i; temp = *k; do { *k = *j; k = j; if (nmemb + array j) { break; } j -= nmemb; } while (GT(j, &temp)); *k = temp; } ++i; } while (i != after); nmemb *= (double)NUMERATOR / DENOMINATOR; } while (nmemb != 0) { i = array + nmemb; do { j = i - nmemb; if (GT(j, i)) { k = i; temp = *k; do { *k = *j; k = j; if (nmemb + array j) { break; } j -= nmemb; } while (GT(j, &temp)); *k = temp; } ++i; } while (i != after); nmemb = (nmemb * NUMERATOR + OFFSET) / DENOMINATOR; } } -- pete Jan 31 '07 #9

 P: n/a Here is what I ended up with: /* For C++ do this: #include template */ void dcss(e_type * array, size_t h) { e_type *i, *j, *k, *after, temp; static const float shell_ratio = 0.31023; size_t inversion = 3; size_t danger_danger = 0; after = array + h; h *= shell_ratio; while (h != 0) { i = array + h; do { j = i - h; if ((*(j) *(i))) { k = i; temp = *k; do { *k = *j; k = j; if (h + array j) { break; } j -= h; } while ((*(j) *(&temp))); *k = temp; } ++i; } while (i != after); h *= shell_ratio; h += danger_danger; danger_danger = (h <= inversion && h 1); } } Try it in your harness, it really smokes. I am going to do a bit more increment hunting, but I am very happy with this one. Jan 31 '07 #10

 P: n/a user923005 wrote: > Here is what I ended up with: /* For C++ do this: #include template */ void dcss(e_type * array, size_t h) { e_type *i, *j, *k, *after, temp; static const float shell_ratio = 0.31023; Should shell_ratio be a double instead of a float? size_t inversion = 3; size_t danger_danger = 0; after = array + h; h *= shell_ratio; while (h != 0) { i = array + h; do { j = i - h; if ((*(j) *(i))) { k = i; temp = *k; do { *k = *j; k = j; if (h + array j) { break; } j -= h; } while ((*(j) *(&temp))); *k = temp; } ++i; } while (i != after); h *= shell_ratio; h += danger_danger; danger_danger = (h <= inversion && h 1); } } Try it in your harness, it really smokes. I am going to do a bit more increment hunting, but I am very happy with this one. It's not bad on my machine. /* BEGIN e_driver.c program output */ Timing 6 different sorting functions. Sorting arrays of N number of elements. The elements are of type long unsigned. sizeof (long unsigned) is 4. The times shown are in seconds. Distribution #1: Shuffled N s2sort s3sort s8sort shsort dcss spsort 1999998 2.516000 2.156000 2.094000 2.172000 2.047000 1.860000 1999999 2.532000 2.157000 2.079000 2.172000 2.078000 1.891000 Total times: s2sort: 5.048000 e_type Shellsort, 1 / 2 increment ratio s3sort: 4.313000 e_type Shellsort, 3 / 7 increment ratio s8sort: 4.173000 e_type Shellsort, 3 / 8 increment ratio shsort: 4.344000 e_type Shellsort, 5 / 11 increment ratio dcss: 4.125000 e_type Shellsort, dcorbit's latest spsort: 3.751000 e_type Shellsort, Sedgewick numbers /* END e_driver.c program output */ -- pete Jan 31 '07 #11

 P: n/a user923005 wrote: On Jan 30, 12:56 pm, pete >user923005 wrote: >>>At any rate, the bit at the end with: if (inc <= inversion && inc 1) { inc = 1; } else inc *= shell_ratio;really gives me the heebie-jeebies (imagining missed branchpredictions). Eventually, I am going to use a rational increment andI also would like to change the calculation for the last increment soit is totally branchless. /* BEGIN s_sort defines */#define NUMERATOR 3#define DENOMINATOR 7#define OFFSET (DENOMINATOR - 2 * NUMERATOR)/* END s_sort defines */inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR;If numerator and denominator are 3 and 8,then you could have: inc = inc + inc + inc + 2 >3; I don't understand how it is supposed to work. I get the increment itself being affected, so obviously I am not using it right: #include /* BEGIN s_sort defines */ #define NUMERATOR 31023 #define DENOMINATOR 100000 #define OFFSET (DENOMINATOR - 2 * NUMERATOR) /* END s_sort defines */ int main(void) { size_t inc = 1000000, jnc = 1000000; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } inc = jnc = 10009711; while (inc 0) { inc = (inc * NUMERATOR + OFFSET) / DENOMINATOR; jnc *= .31023; printf("inc=%u,jnc=%u\n", inc, jnc); } return 0; } /* inc=9582,jnc=310230 inc=2973,jnc=96242 You are apparently getting overflow in the first adjustment. In general, you should not need such large values to get a useable ratio for Shell sort. Try the 3/7 and 3/8 suggested by Pete. -- Thad Jan 31 '07 #12

 P: n/a user923005 wrote: > /* Here is what I ended up with: */ void dcss(e_type * array, size_t h) { e_type *i, *j, *k, *after, temp; static const float shell_ratio = 0.31023; size_t inversion = (size_t) (1.0f / shell_ratio); size_t danger_danger = 0; after = array + h; h *= shell_ratio; while (h != 0) { i = array + h; do { j = i - h; if (GT(j, i)) { k = i; temp = *k; do { *k = *j; k = j; if (h + array j) { break; } j -= h; } while (GT(j, &temp)); *k = temp; } ++i; } while (i != after); h *= shell_ratio; h += danger_danger; danger_danger = (h <= inversion && h 1); } } So? This appears to be code to do something to something. No purpose is evident. It won't even compile as is, lacking a main, etc. See below: -- If you want to post a followup via groups.google.com, ensure you quote enough for the article to make sense. Google is only an interface to Usenet; it's not Usenet itself. Don't assume your readers can, or ever will, see any previous articles. More details at: Jan 31 '07 #13

 P: n/a CBFalconer said: It won't even compile as is, lacking a main, etc. It doesn't need a main to compile. It may not even need a main to link (on freestanding implementations). -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jan 31 '07 #14

 P: n/a CBFalconer wrote: > user923005 wrote: /* Here is what I ended up with: */ void dcss(e_type * array, size_t h) { e_type *i, *j, *k, *after, temp; static const float shell_ratio = 0.31023; size_t inversion = (size_t) (1.0f / shell_ratio); size_t danger_danger = 0; after = array + h; h *= shell_ratio; while (h != 0) { i = array + h; do { j = i - h; if (GT(j, i)) { k = i; temp = *k; do { *k = *j; k = j; if (h + array j) { break; } j -= h; } while (GT(j, &temp)); *k = temp; } ++i; } while (i != after); h *= shell_ratio; h += danger_danger; danger_danger = (h <= inversion && h 1); } } So? This appears to be code to do something to something. No purpose is evident. It won't even compile as is, lacking a main, etc. See below: All it needs to be able to compile are definitions for e_type, size_t and GT(a,b). -- pete Jan 31 '07 #15

 P: n/a Compilable header file: /* // This is a C++ template for shellsort. // It can also be called form C, if e_type has a typedef. // Modification of code by Pete Pfilander by Dann Corbit. // Use it however you like. // Send comments and curses to: dc*****@connx.com */ #ifdef __cplusplus #include #else #include #else #include

 P: n/a P.S. For C, the algorithm still needs a typedef of int for e_type. P.P.S. If this message makes no sense to you, get a threading newsreader. Jan 31 '07 #17

 P: n/a user923005 wrote, On 31/01/07 19:14: P.S. For C, the algorithm still needs a typedef of int for e_type. P.P.S. If this message makes no sense to you, get a threading newsreader. That does not help if the message you are responding to never arrive, of if it arrives some time after this message or if someone reads the message after the response has expired, of if the news reader is set not to show read messages and it is some time since they read the message you are replying to. If that is not enough to encourage you to post properly then consider than most of the knowledgeable people here are likely to either kill file you or ignore you so you will find the group of no use when you need help. -- Flash Gordon Jan 31 '07 #18

 P: n/a Flash Gordon said: user923005 wrote, On 31/01/07 19:14: >P.S.For C, the algorithm still needs a typedef of int for e_type.P.P.S.If this message makes no sense to you, get a threading newsreader. That does not help if the message you are responding to never arrive, of if it arrives some time after this message or if someone reads the message after the response has expired, of if the news reader is set not to show read messages and it is some time since they read the message you are replying to. If that is not enough to encourage you to post properly then consider than most of the knowledgeable people here are likely to either kill file you or ignore you so you will find the group of no use when you need help. Most of the knowledgeable people in this newsgroup know who user923005 is. They know that it would be silly to killfile or ignore him. They know that, on the rare occasions that he asks for help, it's likely to be for extremely interesting reasons. (And yes, they also know that he ought to know better than to post a contextless reply.) -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jan 31 '07 #19

 P: n/a user923005 wrote: > P.S. For C, the algorithm still needs a typedef of int for e_type. P.P.S. If this message makes no sense to you, get a threading newsreader. It has nothing to do with the newsreader, it has to do with the mechanism of usenet. All articles should stand by themselves. -- If you want to post a followup via groups.google.com, ensure you quote enough for the article to make sense. Google is only an interface to Usenet; it's not Usenet itself. Don't assume your readers can, or ever will, see any previous articles. More details at: Jan 31 '07 #20

 P: n/a Richard Heathfield wrote: Most of the knowledgeable people in this newsgroup know who user923005 is. They know that it would be silly to killfile or ignore him. They know that, on the rare occasions that he asks for help, it's likely to be for extremely interesting reasons. (And yes, they also know that he ought to know better than to post a contextless reply.) I can certainly make a guess, but I don't see any reason to give him a pass from standard usenet etiquette. What if he decided next that top-posting was the cat's meow? I try to plonk consistently. If continues to post that way, especially if he's obnoxious about it, then he'll certainly gain a deserved spot in the old killfile. Brian Feb 1 '07 #21

 P: n/a Default User said: Richard Heathfield wrote: >Most of the knowledgeable people in this newsgroup know whouser923005 is. They know that it would be silly to killfile orignore him. They know that, on the rare occasions that he asks forhelp, it's likely to be for extremely interesting reasons. (And yes,they also know that he ought to know better than to post acontextless reply.) I can certainly make a guess, but I don't see any reason to give him a pass from standard usenet etiquette. Neither do I. I suspect that he's just having a bad hair day. What if he decided next that top-posting was the cat's meow? The amount of slack I give people tends to depend on their S/N ratio (signal to noise, sense to nonsense, skill to nuisance, whatever fits). This tiny increase in N from user923005 doesn't significantly reduce his S/N ratio, but obviously top-posting would increase N still further, and eventually there would come a point... but I don't think that point is now. YMMV, of course. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Feb 1 '07 #22

 P: n/a "Richard Heathfield" user923005 wrote, On 31/01/07 19:14: >>P.S.For C, the algorithm still needs a typedef of int for e_type.P.P.S.If this message makes no sense to you, get a threading newsreader. That does not help if the message you are responding to never arrive, ofif it arrives some time after this message or if someone reads themessage after the response has expired, of if the news reader is set notto show read messages and it is some time since they read the messageyou are replying to.If that is not enough to encourage you to post properly then considerthan most of the knowledgeable people here are likely to either killfile you or ignore you so you will find the group of no use when youneed help. Most of the knowledgeable people in this newsgroup know who user923005 is. They know that it would be silly to killfile or ignore him. They know that, on the rare occasions that he asks for help, it's likely to be for extremely interesting reasons. (And yes, they also know that he ought to know better than to post a contextless reply.) Before he gets a disintegration ray, would he comment on how he came up with the theoretical worst case performance in Figs. 13.7 and 13.8 without handpicking "bad" initial sets? LS Feb 1 '07 #23

 P: n/a Richard Heathfield wrote: Default User said: Richard Heathfield wrote: Most of the knowledgeable people in this newsgroup know who user923005 is. They know that it would be silly to killfile or ignore him. They know that, on the rare occasions that he asks for help, it's likely to be for extremely interesting reasons. (And yes, >they also know that he ought to know better than to post a contextless reply.) I can certainly make a guess, but I don't see any reason to give him a pass from standard usenet etiquette. Neither do I. I suspect that he's just having a bad hair day. What if he decided next that top-posting was the cat's meow? The amount of slack I give people tends to depend on their S/N ratio (signal to noise, sense to nonsense, skill to nuisance, whatever fits). This tiny increase in N from user923005 doesn't significantly reduce his S/N ratio, but obviously top-posting would increase N still further, and eventually there would come a point... but I don't think that point is now. YMMV, of course. I just can't agree with that sort of evaluation. I try to be as consistent as I can, as I think "rules" such as they are in an unmoderated group should apply as equally as possible. Allowing the "regulars" to flout the rules that we hammer newbies about sends exactly the wrong message, and gives fuel to the trolls who maintain that that's the norm here. The fact that someone has made useful contributions historically doesn't hold a lot of weight with me. Some, I guess, maybe as you say, let one bad day slide. However, if it's appearing to be a continuing policy, then I'm not going to calculate some S/N ratio. Brian Feb 1 '07 #24

 P: n/a Default User said: I just can't agree with that sort of evaluation. I try to be as consistent as I can, as I think "rules" such as they are in an unmoderated group should apply as equally as possible. So do I. I cut *everybody* slack in proportion to their S/N ratio. Allowing the "regulars" to flout the rules that we hammer newbies about sends exactly the wrong message, You're not *allowing* him to do anything. He can do what he likes, without regard to your opinion or mine or anyone else's. The only control you have is over *your* behaviour - your reaction to what he posts. and gives fuel to the trolls who maintain that that's the norm here. Trolls don't need fuel. They just make stuff up. > The fact that someone has made useful contributions historically doesn't hold a lot of weight with me. Some, I guess, maybe as you say, let one bad day slide. However, if it's appearing to be a continuing policy, then I'm not going to calculate some S/N ratio. Well, neither am I. If someone posts a great many superb articles a day and top-posts one or two from time to time, and forgets to quote context in another handful, is it truly sensible to reprimand them for that? On the other hand, if someone posts a handful of rather mediocre articles a day, and top-posts in most of them, and fails to quote context in nearly all of them, is it truly sensible *not* to? At some point, you strike a balance. You don't need to dig out a pocket calculator to know when someone "gets" it and when they don't. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Feb 1 '07 #25

### This discussion thread is closed

Replies have been disabled for this discussion.