|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I have this code here, it converts decimal numbers to binary. There is
one problem. The output is printed 'in reverse' and I have no clue at all how to solve this problem. Output of program: Decimal number: 10 Binary representation: 0101 (It should be 1010, and not 0101...) I would be glad if someone could me. Maybe there is some function, which does the trick... (I have no idea.) Thanks. /************************************************** ********************/ #include <stdio.h> #include <string.h> int main() { char bin[25] = ""; int dec; printf("Decimal number: "); scanf("%d", &dec); do { if (dec % 2 == 0) strcat(bin, "0"); else { strcat(bin, "1"); dec--; } dec = dec / 2; } while (dec > 0); printf("Binary representation: %s\n", bin); return 0; } /************************************************** ********************/ |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
hank wrote:
> I have this code here, it converts decimal numbers to binary. There is > one problem. The output is printed 'in reverse' and I have no clue at > all how to solve this problem. > > Output of program: > > Decimal number: 10 > Binary representation: 0101 > (It should be 1010, and not 0101...) > > I would be glad if someone could me. Maybe there is some > function, which does the trick... (I have no idea.) You could reverse the string in place before printing it. There is no standard string reverse function, but it's easy enough to write one. As an alternative you could just iterate backwards through the string while printing it, character by character. <snip> |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
santosh wrote:
> hank wrote: > >> I have this code here, it converts decimal numbers to binary. There is >> one problem. The output is printed 'in reverse' and I have no clue at >> all how to solve this problem. > > You could reverse the string in place before printing it. Or you could write it correctly. /************************************************** ********************/ #include <stdio.h> #include <string.h> void fprint_binary_representation(FILE *out, unsigned char byte) { char str_rep[9] = {0}; int i; for (i = 7; i >= 0; i--) { str_rep[7 - i] = ((byte & (1 << i)) ? '1' : '0'); } fprintf(out, "%s", str_rep); } int main() { fprint_binary_representation(stdout, 10); // prints 00001010 return 0; } /************************************************** ********************/ |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
> You could reverse the string in place before printing it. There is no
> standard string reverse function, but it's easy enough to write one. As > an alternative you could just iterate backwards through the string > while printing it, character by character. > > <snip> Here's what I should do. (Put this after the do-while{} loop) //////////////////////////////////////////////////////////////////////// length = strlen(bin); int i; for (i = length - 1; i >= 0; i--) { printf("%c", bin[i]); } /////////////////////////////////////////////////////////////////////// |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
> santosh wrote: >> You could reverse the string in place before printing it. Andrew Kerr wrote: > Or you could write it correctly. Correctly... which is reversing the string in place before printing it. Sorry about that comment, I'm an ass. -- Andrew Kerr |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
In comp.lang.c, sohijb.edrisy@gmail.com wrote:
>> You could reverse the string in place before printing it. There is no >> standard string reverse function, but it's easy enough to write one. As >> an alternative you could just iterate backwards through the string >> while printing it, character by character. >> >> <snip> > > Here's what I should do. > > (Put this after the do-while{} loop) > > //////////////////////////////////////////////////////////////////////// > length = strlen(bin); > int i; > > for (i = length - 1; i >= 0; i--) > { > printf("%c", bin[i]); > } > /////////////////////////////////////////////////////////////////////// How about... void RevPrint(char *string) { if (*string) { RevPrint(string+1); printf("%c",*string); } } used as... printf("Binary representation: "); RevPrint(bin); -- Lew Pitcher Master Codewright & JOAT-in-training | Registered Linux User #112576 http://pitcher.digitalfreehold.ca/ | GPG public key available by request ---------- Slackware - Because I know what I'm doing. ------ |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
sohijb.edrisy@gmail.com wrote:
> .... snip ... > > ///////////////////////////////////////////////////////////////// > length = strlen(bin); > int i; > > for (i = length - 1; i >= 0; i--) > { > printf("%c", bin[i]); > } > ///////////////////////////////////////////////////////////////// All those silly division symbols create syntax errors on C90. :-) -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com ** |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On May 30, 8:34pm, hank <ilona-radema...@hotmail.com> wrote:
> do { > if (dec % 2 == 0) > strcat(bin, "0"); > else { > strcat(bin, "1"); > dec--; > } > dec = dec / 2; > } while (dec > 0); This algorithm can be written differently depending on whether you do or do not want leading zeroes. My major criticism of your original code is that it takes a human approach rather than a computer approach. A computer approach would be to use (x & 1) instead of (x % 2), and also to use shifting instead of division by 2. If I didn't want leading zeroes, I'd go with something like the following: (Disclaimer: Untested code thrown together in the last two minutes) #define QUANTITY_VALUE_BITS(int_type) /* fancy macro */ void GetBinary(unsigned const val, char *p) { unsigned mask = 1u << (QUANTITY_VALUE_BITS(unsigned) - 1); do if (val & mask) goto We_Have_Ones; while (mask >> = 1); /* If here is reached, there's no 1's */ p[0] = '0'; p[1] = 0; return; /* <--- And we're gone! */ We_Have_Ones: *p++ = '1'; while (mask >>= 1) *p++ = (val & mask ? '1' : '0'); *p = 0; } |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Tomás Ó hÉilidhe wrote:
> On May 30, 8:34 pm, hank <ilona-radema...@hotmail.com> wrote: > >> do { >> if (dec % 2 == 0) >> strcat(bin, "0"); >> else { >> strcat(bin, "1"); >> dec--; >> } >> dec = dec / 2; >> } while (dec > 0); > > > This algorithm can be written differently depending on whether you do > or do not want leading zeroes. > > My major criticism of your original code is that it takes a human > approach rather than a computer approach. A computer approach would be > to use (x & 1) instead of (x % 2), and also to use shifting instead of > division by 2. I disagree. The code as written, is easy to understand. If he were doing decimal representation, he would be dividing by 10 instead. It's entirely possible and likely that a compiler will know as much as you do about these simple micro-optimizations and generate the same machine code for (x & 1) as it does for (x % 2). If the code is shown to be not fast enough, then I would investigate the changes that you suggest, otherwise legibility is a higher priority. -- pete |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
pete <pfiland@mindspring.com> writes:
> Tomás Ó hÉilidhe wrote: >> On May 30, 8:34 pm, hank <ilona-radema...@hotmail.com> wrote: >> >>> do { >>> if (dec % 2 == 0) >>> strcat(bin, "0"); >>> else { >>> strcat(bin, "1"); >>> dec--; >>> } >>> dec = dec / 2; >>> } while (dec > 0); >> >> >> This algorithm can be written differently depending on whether you do >> or do not want leading zeroes. >> >> My major criticism of your original code is that it takes a human >> approach rather than a computer approach. A computer approach would be >> to use (x & 1) instead of (x % 2), and also to use shifting instead of >> division by 2. > > I disagree. > The code as written, is easy to understand. > If he were doing decimal representation, > he would be dividing by 10 instead. > > It's entirely possible and likely that a compiler > will know as much as you do about these simple micro-optimizations > and generate the same machine code for (x & 1) as it does for (x % 2). > > If the code is shown to be not fast enough, > then I would investigate the changes that you suggest, > otherwise legibility is a higher priority. If the code was being maintained by Bill possibly. But if a C programmer does not understand something x&1 or shift right/left then they have no business writing in C in a commercial setting. |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Richard<rgrdev@gmail.com> writes:
> pete <pfiland@mindspring.com> writes: > >> Tomás Ó hÉilidhe wrote: <snip> >>> My major criticism of your original code is that it takes a human >>> approach rather than a computer approach. A computer approach would be >>> to use (x & 1) instead of (x % 2), and also to use shifting instead of >>> division by 2. >> >> I disagree. >> The code as written, is easy to understand. >> If he were doing decimal representation, >> he would be dividing by 10 instead. >> >> It's entirely possible and likely that a compiler >> will know as much as you do about these simple micro-optimizations >> and generate the same machine code for (x & 1) as it does for (x % 2). >> >> If the code is shown to be not fast enough, >> then I would investigate the changes that you suggest, >> otherwise legibility is a higher priority. > > If the code was being maintained by Bill possibly. But if a C programmer > does not understand something x&1 or shift right/left then they have no > business writing in C in a commercial setting. But what of pete's first point? I much prefer % and / in the context because it expresses a general algorithm. Even if asked to do just base 2, might be tempted to write: #define BASE 2 #define DIGITS "01" .... while (num) { *--p = DIGITS[num %ÂBASE]; num /= BASE; } just because it is so self-documenting and obviously extensible. The shift/mask method is entirely understandable, but it obscures (ever so slightly) the algorithm. -- Ben. |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Richard<rgrdev@gmail.com> writes: > >> pete <pfiland@mindspring.com> writes: >> >>> Tomás Ó hÉilidhe wrote: > <snip> >>>> My major criticism of your original code is that it takes a human >>>> approach rather than a computer approach. A computer approach would be >>>> to use (x & 1) instead of (x % 2), and also to use shifting instead of >>>> division by 2. >>> >>> I disagree. >>> The code as written, is easy to understand. >>> If he were doing decimal representation, >>> he would be dividing by 10 instead. >>> >>> It's entirely possible and likely that a compiler >>> will know as much as you do about these simple micro-optimizations >>> and generate the same machine code for (x & 1) as it does for (x % 2). >>> >>> If the code is shown to be not fast enough, >>> then I would investigate the changes that you suggest, >>> otherwise legibility is a higher priority. >> >> If the code was being maintained by Bill possibly. But if a C programmer >> does not understand something x&1 or shift right/left then they have no >> business writing in C in a commercial setting. > > But what of pete's first point? I much prefer % and / in the context > because it expresses a general algorithm. Even if asked to do just > base 2, might be tempted to write: > > #define BASE 2 > #define DIGITS "01" > > ... > > while (num) { > *--p = DIGITS[num %ÂBASE]; > num /= BASE; > } > > just because it is so self-documenting and obviously extensible. The > shift/mask method is entirely understandable, but it obscures (ever so > slightly) the algorithm. I have no problem with his code, but I would suggest that (especially the shift) the bit test and the shift are obvious to any half decent C programmer. |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Richard<rgrdev@gmail.com> writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> Richard<rgrdev@gmail.com> writes: >> >>> pete <pfiland@mindspring.com> writes: <snip> >>>> I disagree. >>>> The code as written, is easy to understand. >>>> If he were doing decimal representation, >>>> he would be dividing by 10 instead. <snip other points> >>> If the code was being maintained by Bill possibly. But if a C programmer >>> does not understand something x&1 or shift right/left then they have no >>> business writing in C in a commercial setting. >> >> But what of pete's first point? I much prefer % and / in the context >> because it expresses a general algorithm. <snip> > I have no problem with his code, but I would suggest that (especially > the shift) the bit test and the shift are obvious to any half decent C > programmer. Right and I agreed. I wondered if you had anything to add about his first point which is not about whether anyone should or should not be able to read the alternative. -- Ben. |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Richard<rgrdev@gmail.com> writes: > >> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >> >>> Richard<rgrdev@gmail.com> writes: >>> >>>> pete <pfiland@mindspring.com> writes: > <snip> >>>>> I disagree. >>>>> The code as written, is easy to understand. >>>>> If he were doing decimal representation, >>>>> he would be dividing by 10 instead. > <snip other points> >>>> If the code was being maintained by Bill possibly. But if a C programmer >>>> does not understand something x&1 or shift right/left then they have no >>>> business writing in C in a commercial setting. >>> >>> But what of pete's first point? I much prefer % and / in the context >>> because it expresses a general algorithm. > <snip> >> I have no problem with his code, but I would suggest that (especially >> the shift) the bit test and the shift are obvious to any half decent C >> programmer. > > Right and I agreed. I wondered if you had anything to add about his > first point which is not about whether anyone should or should not be > able to read the alternative. If you are talking about the compiler part and the optimisation then yes, of course I agree with him. There is often a misty area with certain code constructs. I would generally go for maintainability over obscure nano second saving techniques. In this case however, >>1 is as clear as /2 for me. However, I remember seeing someone (I think it was Chuck) complaining about while(*d++=*s++); as being a "misuse" of the language. To me this *IS* C and if you have any issue with it then you should not be programming in C. C is not Pascal or Ada. I have been involved in a lot of large projects with shifting maintainer base. And never once have we advocated programming for the weakest link. We program for competent C programmers not for someone with no programming experience. A good programmer will pick up things very, very quickly. The only real thing I always insisted on was never, ever have conditional result blocks on the same line as the conditional as Falconer seems to favour. e.g if(f){ i=f2(i); } is infinitely better than if(f) i=f2(i); I always structure code to faciliate *other people* to set inquisitive break points. But we've all been down that alley here before and I really don't want to hear from the usual suspects about how they once debugged 5000000 lines by simply reading the code as if that somehow meant a debugger was useless for all. |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
On Jun 1, 12:22am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> #define BASE 2 > #define DIGITS "01" #define DIGITS "01" #define BASE (sizeof digits - 1) :-D To make the trully perfect algorithm for this, you'd need to know: 1) Whether there should be trailing zeroes 2) Whether it's OK to return a pointer which is a few bytes ahead of the supplied pointer. For example: (Disclaimer: Untested code thrown together in a few minutes) #define DIGITS "0123456789abcdef" #define BASE (sizeof digits - 1) void Convert(unsigned const val, char *p) { char *q = p; /* Keep track of the first address */ /* --- First write the string backwards --- */ do *p++ = DIGITS[val % BASE]; while (val /= BASE); *p-- = 0; /* Write the null and point p to the last char */ /* --- Now reverse the string --- */ for ( ; q > p; ++q, --p) { char const temp = *q; *q = *p; *p = temp; } } |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
Tomás Ó hÉilidhe wrote:
> On Jun 1, 12:22 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote: > >> #define BASE 2 >> #define DIGITS "01" > > > #define DIGITS "01" > > #define BASE (sizeof digits - 1) #define BASE (sizeof DIGITS - 1) <snip> Bye, Jojo |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
Richard<rgrdev@gmail.com> writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> Richard<rgrdev@gmail.com> writes: >> >>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>> >>>> Richard<rgrdev@gmail.com> writes: >>>> >>>>> pete <pfiland@mindspring.com> writes: >> <snip> >>>>>> I disagree. >>>>>> The code as written, is easy to understand. >>>>>> If he were doing decimal representation, >>>>>> he would be dividing by 10 instead. >> <snip other points> >>>>> If the code was being maintained by Bill possibly. But if a C programmer >>>>> does not understand something x&1 or shift right/left then they have no >>>>> business writing in C in a commercial setting. >>>> >>>> But what of pete's first point? I much prefer % and / in the context >>>> because it expresses a general algorithm. >> <snip> >>> I have no problem with his code, but I would suggest that (especially >>> the shift) the bit test and the shift are obvious to any half decent C >>> programmer. >> >> Right and I agreed. I wondered if you had anything to add about his >> first point which is not about whether anyone should or should not be >> able to read the alternative. > > If you are talking about the compiler part and the optimisation then > yes, of course I agree with him. > > There is often a misty area with certain code constructs. I would > generally go for maintainability over obscure nano second saving > techniques. In this case however, >>1 is as clear as /2 for me. That confuses meaning with intent. Understanding code happens at multiple levels. The meaning of both may be equally clear, but one expresses the intent more directly. Having said that, I'd even go as far as to say that they are *not* as quite clear as each other. You have to know more about the code to be sure that >>1 is doing what you want than do with /2. The particular case in question is interesting. Follow the thread up and you will see that >>1 requires both of us to check the implementation's documentation to know what the code would do when the input is negative. I don't need to do that to understand the OP's code because it used /2. <snip> > The only real thing I always insisted on was never, ever have > conditional result blocks on the same line as the conditional I can't get worked up about layout, just as I can't get worked up about the return type of main. Both are trivial to fix. I once worked with an inveterate single space indenter and in the end we just added a make target for our preferred indent settings. As his boss, I could have insisted but then I would have risked annoying an otherwise brilliant programmer for no good technical reason. <snip> > I > really don't want to hear from the usual suspects about how they once > debugged 5000000 lines by simply reading the code as if that somehow > meant a debugger was useless for all. Yes, that would be an extraordinary conclusion to draw from such a story but, as far as I can tell, the only people every to have suggested it are people in the pro-debugger camp who want to over-state the opposing case. Everyone who expressed the view that they find a debugger less that essential (for things other than a back-trace) seemed to accept that this was a personal preference. -- Ben. |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
Tomás Ó hÉilidhe <toe@lavabit.com> writes:
> On Jun 1, 12:22Âam, Ben Bacarisse <ben.use...@bsb.me.uk> wrote: > >> #define BASE 2 >> #define DIGITS "01" > > > #define DIGITS "01" > > #define BASE (sizeof digits - 1) > :-D #define BASE (sizeof DIGITS - 1) :-D -- Ben. |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Richard<rgrdev@gmail.com> writes: > >> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >> >>> Richard<rgrdev@gmail.com> writes: >>> >>>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>>> >>>>> Richard<rgrdev@gmail.com> writes: >>>>> >>>>>> pete <pfiland@mindspring.com> writes: >>> <snip> >>>>>>> I disagree. >>>>>>> The code as written, is easy to understand. >>>>>>> If he were doing decimal representation, >>>>>>> he would be dividing by 10 instead. >>> <snip other points> >>>>>> If the code was being maintained by Bill possibly. But if a C programmer >>>>>> does not understand something x&1 or shift right/left then they have no >>>>>> business writing in C in a commercial setting. >>>>> >>>>> But what of pete's first point? I much prefer % and / in the context >>>>> because it expresses a general algorithm. >>> <snip> >>>> I have no problem with his code, but I would suggest that (especially >>>> the shift) the bit test and the shift are obvious to any half decent C >>>> programmer. >>> >>> Right and I agreed. I wondered if you had anything to add about his >>> first point which is not about whether anyone should or should not be >>> able to read the alternative. >> >> If you are talking about the compiler part and the optimisation then >> yes, of course I agree with him. >> >> There is often a misty area with certain code constructs. I would >> generally go for maintainability over obscure nano second saving >> techniques. In this case however, >>1 is as clear as /2 for me. > > That confuses meaning with intent. Understanding code happens at To some. My point here is that it would not for me in the context of the code. > multiple levels. The meaning of both may be equally clear, but one > expresses the intent more directly. Not really. Not in the context. >>1 reads to me the same as /2. For me that is. However I do not give bonus points to someone using >>1 for them being "elite". > > Having said that, I'd even go as far as to say that they are *not* as > quite clear as each other. You have to know more about the code to be > sure that >>1 is doing what you want than do with /2. The particular Obviously - I assumed we had that covered. > case in question is interesting. Follow the thread up and you will > see that >>1 requires both of us to check the implementation's > documentation to know what the code would do when the input is > negative. I don't need to do that to understand the OP's code because > it used /2. Agreed. See "context" mentioned above. > > <snip> >> The only real thing I always insisted on was never, ever have >> conditional result blocks on the same line as the conditional > > I can't get worked up about layout, just as I can't get worked up > about the return type of main. Both are trivial to fix. I once No they are not. They are far from trivial to fix and layout and refactoring ofetn introduce many bugs because of human error. In *my* experience of *large* projects with *many* programmers then a consistent layout and debugger friendly layout is a must. Fixing layout means checking out, fixing, submitting for testing etc. Much better to get it tight the first time. > worked with an inveterate single space indenter and in the end we just > added a make target for our preferred indent settings. As his boss, I > could have insisted but then I would have risked annoying an otherwise > brilliant programmer for no good technical reason. I see it another way : if he is really that good then he will appreciate the needs for a uniform code style on large projects. > > <snip> >> I >> really don't want to hear from the usual suspects about how they once >> debugged 5000000 lines by simply reading the code as if that somehow >> meant a debugger was useless for all. > > Yes, that would be an extraordinary conclusion to draw from such a > story but, as far as I can tell, the only people every to have > suggested it are people in the pro-debugger camp who want to pro-debugger? You mean anti-debugger? > over-state the opposing case. Everyone who expressed the view that > they find a debugger less that essential (for things other than a > back-trace) seemed to accept that this was a personal preference. That is most certainly not the case. The case supported by most regs was based on the fact that they personally rarely used a debugger. And my opinion of this was that most were simply posing or really had no clue how to properly use one. It is impossible for a debugger to make your life harder. It can only . The rest is really a natural conclusion and follow on. |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
On Fri, 30 May 2008 19:34:17 +0000, hank wrote:
> I have this code here, it converts decimal numbers to binary. There is > one problem. The output is printed 'in reverse' and I have no clue at > all how to solve this problem. > > Output of program: > > Decimal number: 10 > Binary representation: 0101 > (It should be 1010, and not 0101...) > > I would be glad if someone could me. Maybe there is some function, > which does the trick... (I have no idea.) > > Thanks. > > /************************************************** ********************/ > #include <stdio.h> > #include <string.h> > > int main() > { > char bin[25] = ""; > int dec; > > printf("Decimal number: "); > scanf("%d", &dec); > > do { > if (dec % 2 == 0) > strcat(bin, "0"); > else { > strcat(bin, "1"); > dec--; > } > dec = dec / 2; > } while (dec > 0); > printf("Binary representation: %s\n", bin); > > return 0; > } > /************************************************** ********************/ After spending some hours hacking and searching the Web, I came up with this solution. The other solutions posted here by different people are great, but they are too difficult... Instead of saving the numbers in an array and iterating through them backwards, you could use recursion. Without using recursion, the algorithm calculates the final digit first. You would have to store all the digits somewhere before displaying them. The following code is from 'C Primer Plus'. (Yeah, i'm a n00b...) /************************************************** ***************/ /* binary.c -- prints integer in binary form */ #include <stdio.h> void to_binary(unsigned long n); int main() { unsigned long number; printf("Enter an integer (q to quit): \n"); while (scanf("%ul", &number) == 1) { printf("Binary equivalent: "); to_binary(number); putchar('\n'); printf("Enter an integer: "); } return 0; } /* to_binary: recursive function */ void to_binary(unsigned long n) { int r; r = n % 2; if (n >= 2) to_binary(n / 2); putchar('0' + r); return; } /************************************************** ***************/ |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
On Jun 1, 8:32pm, Sohijb Edrisy <sohijb.edr...@gmail.com> wrote:
> /* to_binary: recursive function */ > void to_binary(unsigned long n) > { > int r; > > r = n % 2; > if (n >= 2) > to_binary(n / 2); > putchar('0' + r); > > return; >} This is neat and all but it's HORRIBLY inefficient, both in terms of the execution time and also the amount of stack space it eats up. |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
Tomás Ó hÉilidhe wrote:
> Sohijb Edrisy <sohijb.edr...@gmail.com> wrote: > >> /* to_binary: recursive function */ >> void to_binary(unsigned long n) { >> int r; >> >> r = n % 2; >> if (n >= 2) >> to_binary(n / 2); >> putchar('0' + r); >> return; >>} > > This is neat and all but it's HORRIBLY inefficient, both in terms of > the execution time and also the amount of stack space it eats up. No it isn't. It is far and away the best method, assuming sufficient stack for about 32 recursion levels. It can be simplified to: void to_bin(unsigned long n) { if (n > 1) to_bin(n / 2); putchar('0' + (n % 2); } -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com ** |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
CBFalconer wrote:
> Tomás Ó hÉilidhe wrote: >> Sohijb Edrisy <sohijb.edr...@gmail.com> wrote: >> >>> /* to_binary: recursive function */ >>> void to_binary(unsigned long n) { >>> int r; >>> >>> r = n % 2; >>> if (n >= 2) >>> to_binary(n / 2); >>> putchar('0' + r); >>> return; >>> } >> This is neat and all but it's HORRIBLY inefficient, both in terms of >> the execution time and also the amount of stack space it eats up. > > No it isn't. It is far and away the best method, assuming > sufficient stack for about 32 recursion levels. Agreed, a good example of how recursion can lead to elegant and expressive code. > It can be simplified to: > > void to_bin(unsigned long n) { > > if (n > 1) to_bin(n / 2); > putchar('0' + (n % 2); ^ ) > } > -- Ian Collins. |
|
|
|
#24 |
|
Messages: n/a
Hébergeur: |
Richard<rgrdev@gmail.com> writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> Richard<rgrdev@gmail.com> writes: >> >>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>> >>>> Richard<rgrdev@gmail.com> writes: >>>> >>>>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>>>> >>>>>> Richard<rgrdev@gmail.com> writes: >>>>>> >>>>>>> pete <pfiland@mindspring.com> writes: >>>> <snip> >>>>>>>> I disagree. >>>>>>>> The code as written, is easy to understand. >>>>>>>> If he were doing decimal representation, >>>>>>>> he would be dividing by 10 instead. >>>> <snip other points> >>>>>>> If the code was being maintained by Bill possibly. But if a C programmer >>>>>>> does not understand something x&1 or shift right/left then they have no >>>>>>> business writing in C in a commercial setting. >>>>>> >>>>>> But what of pete's first point? I much prefer % and / in the context >>>>>> because it expresses a general algorithm. >>>> <snip> >>>>> I have no problem with his code, but I would suggest that (especially >>>>> the shift) the bit test and the shift are obvious to any half decent C >>>>> programmer. >>>> >>>> Right and I agreed. I wondered if you had anything to add about his >>>> first point which is not about whether anyone should or should not be >>>> able to read the alternative. >>> >>> If you are talking about the compiler part and the optimisation then >>> yes, of course I agree with him. >>> >>> There is often a misty area with certain code constructs. I would >>> generally go for maintainability over obscure nano second saving >>> techniques. In this case however, >>1 is as clear as /2 for me. >> >> That confuses meaning with intent. Understanding code happens at > > To some. My point here is that it would not for me in the context of the > code. > >> multiple levels. The meaning of both may be equally clear, but one >> expresses the intent more directly. > > Not really. Not in the context. >>1 reads to me the same as /2. Well we are talking at cross-purposes then. I saw only one context and in that context >>1 |