日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[算法]不使用*、/、+、-、%操作符求一个数的1/3

發(fā)布時(shí)間:2023/12/18 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [算法]不使用*、/、+、-、%操作符求一个数的1/3 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
摘要:算法一直是程序員進(jìn)階的一道龍門(mén),通常算法都是為了更高效地解決問(wèn)題而創(chuàng)造的,但也有的只是出于學(xué)術(shù)性,并不在意其實(shí)際意義。這是近日在國(guó)外技術(shù)問(wèn)答網(wǎng)站stackoverflow的一個(gè)熱門(mén)問(wèn)題,不知道你能給出幾種解決方法?

導(dǎo)讀:算法一直是程序員進(jìn)階的一道龍門(mén),通常算法都是為了更高效地解決問(wèn)題而創(chuàng)造的,但也有的只是出于學(xué)術(shù)性,并不在意其實(shí)際意義。這是近日在國(guó)外技術(shù)問(wèn)答網(wǎng)站stackoverflow的一個(gè)熱門(mén)問(wèn)題,不知道你能給出幾種解決方法?

問(wèn):在不使用*、/、+、-、%操作符的情況下,如何求一個(gè)數(shù)的1/3?(用C語(yǔ)言實(shí)現(xiàn))

第一種方法:使用位操作符并實(shí)現(xiàn)“+”操作

  • //?替換加法運(yùn)算符?
  • int?add(int?x,?int?y)?{?
  • ????int?a,?b;?
  • ????do?{?
  • ????????a?=?x?&?y;?
  • ????????b?=?x?^?y;?
  • ????????x?=?a?<<?1;?
  • ????????y?=?b;?
  • ????}?while?(a);?
  • ????return?b;?
  • }?
  • ?
  • int?divideby3?(int?num)?{?
  • ????int?sum?=?0;?
  • ????while?(num?>?3)?{?
  • ????????sum?=?add(num?>>?2,?sum);?
  • ????????num?=?add(num?>>?2,?num?&?3);?
  • ????}?
  • ????if?(num?==?3)?
  • ????????sum?=?add(sum,?1);?
  • ????return?sum;??
  • }?
  • 原理:n = 4 * a + b; n / 3 = a + (a + b) / 3; 然后 sum += a, n = a + b 并迭代; 當(dāng) a == 0 (n < 4)時(shí),sum += floor(n / 3); i.e. 1, if n == 3, else 0

    第二種方法:

  • #include?<stdio.h>?
  • #include?<stdlib.h>?
  • int?main()?
  • {?
  • ????FILE?*?fp=fopen("temp.dat","w+b");?
  • ????int?number=12346;?
  • ????int?divisor=3;?
  • ????char?*?buf?=?calloc(number,1);?
  • ????fwrite(buf,number,1,fp);?
  • ????rewind(fp);?
  • ????int?result=fread(buf,divisor,number,fp);?
  • ????printf("%d?/?%d?=?%d",?number,?divisor,?result);?
  • ????free(buf);?
  • ????fclose(fp);?
  • ????return?0;?
  • }?
  • 第三種方法:

  • log(pow(exp(number),0.33333333333333333333))?/*?:-)?*/?
  • 增強(qiáng)版:

  • log(pow(exp(number),sin(atan2(1,sqrt(8)))))??
  • 第四種方法:

  • #include?<stdio.h>?
  • #include?<stdlib.h>?
  • int?main(int?argc,?char?*argv[])?
  • {?
  • ????int?num?=?1234567;?
  • ????int?den?=?3;?
  • ????div_t?r?=?div(num,den);?//?div()是標(biāo)準(zhǔn)C語(yǔ)言函數(shù)
  • ????printf("%d\n",?r.quot);?
  • ????return?0;?
  • }?
  • 第五種方法:使用內(nèi)聯(lián)匯編

  • #include?<stdio.h>?
  • int?main()?{?
  • ??int?dividend?=?-42,?divisor?=?3,?quotient,?remainder;?
  • ?
  • ??__asm__?(?"movl???%2,?%%edx;"?
  • ????????????"sarl??$31,?%%edx;"?
  • ????????????"movl???%2,?%%eax;"?
  • ????????????"movl???%3,?%%ebx;"?
  • ????????????"idivl??????%%ebx;"?
  • ??????????:?"=a"?(quotient),?"=d"?(remainder)?
  • ??????????:?"g"??(dividend),?"g"??(divisor)?
  • ??????????:?"ebx"?);?
  • ?
  • ??printf("%i?/?%i?=?%i,?remainder:?%i\n",?dividend,?divisor,?quotient,?remainder);?
  • }?
  • 第六種方法:

  • //?注意:?itoa?不是個(gè)標(biāo)準(zhǔn)函數(shù),但它可以實(shí)現(xiàn)
  • //?don't?seem?to?handle?negative?when?base?!=?10?
  • int?div3(int?i)?{?
  • ??char?str[42];?
  • ??sprintf(str,?"%d",?INT_MIN);?//?put?minus?sign?at?str[0]?
  • ??if?(i>0)?str[0]?=?'?';???????//?remove?sign?if?positive?
  • ??itoa(abs(i),?&str[1],?3);????//?put?ternary?absolute?value?starting?at?str[1]?
  • ??str[strlen(&str[1])]?=?'\0';?//?drop?last?digit?
  • ??return?strtol(str,?NULL,?3);?//?read?back?result?
  • }?
  • 第七種方法:

  • unsigned?div_by(unsigned?const?x,?unsigned?const?by)?{?
  • ??unsigned?floor?=?0;?
  • ??for?(unsigned?cmp?=?0,?r?=?0;?cmp?<=?x;)?{?
  • ????for?(unsigned?i?=?0;?i?<?by;?i++)?
  • ??????cmp++;?//?這是++操作符,不是+?
  • ????floor?=?r;?
  • ????r++;?//?這也不是?
  • ??}?
  • ??return?floor;?
  • }?
  • 替換掉上面算法的++運(yùn)算符:

  • unsigned?inc(unsigned?x)?{?
  • ??for?(unsigned?mask?=?1;?mask;?mask?<<=?1)?{?
  • ????if?(mask?&?x)?
  • ??????x?&=?~mask;?
  • ????else?
  • ??????return?x?&?mask;?
  • ??}?
  • ??return?0;?//?溢出(注意:這里的x和mask都是0)
  • }?
  • 這個(gè)版本更快一些:

  • unsigned?add(char?const?zero[],?unsigned?const?x,?unsigned?const?y)?{?
  • ??//?這是因?yàn)?#xff1a;如果foo是char*類(lèi)型,?&foo[bar]?==?foo+bar
  • ??return?(int)(uintptr_t)(&((&zero[x])[y]));?
  • }?
  • ?
  • unsigned?div_by(unsigned?const?x,?unsigned?const?by)?{?
  • ??unsigned?floor?=?0;?
  • ??for?(unsigned?cmp?=?0,?r?=?0;?cmp?<=?x;)?{?
  • ????cmp?=?add(0,cmp,by);?
  • ????floor?=?r;?
  • ????r?=?add(0,r,1);?
  • ??}?
  • ??return?floor;?
  • }?
  • 第八種方法:實(shí)現(xiàn)乘法

  • int?mul(int?const?x,?int?const?y)?{?
  • ??return?sizeof(struct?{?
  • ????char?const?ignore[y];?
  • ??}[x]);?
  • }?
  • 第九種方法:極限

  • public?static?int?div_by_3(long?a)?{?
  • ????a?<<=?30;?
  • ????for(int?i?=?2;?i?<=?32?;?i?<<=?1)?{?
  • ????????a?=?add(a,?a?>>?i);?
  • ????}?
  • ????return?(int)?(a?>>?32);?
  • }?
  • ?
  • public?static?long?add(long?a,?long?b)?{?
  • ????long?carry?=?(a?&?b)?<<?1;?
  • ????long?sum?=?(a?^?b);?
  • ????return?carry?==?0???sum?:?add(carry,?sum);?
  • }?
  • 原理:

    因?yàn)?#xff0c; 1/3 = 1/4 + 1/16 + 1/64 + ...

    所以,

    a/3 = a * 1/3 ?

    a/3 = a * (1/4 + 1/16 + 1/64 + ...)

    a/3 = a/4 + a/16 + 1/64 + ...

    a/3 = a >> 2 + a >> 4 + a >> 6 + ...

    第十種方法:

  • public?static?int?DivideBy3(int?a)?{?
  • ????bool?negative?=?a?<?0;?
  • ????if?(negative)?a?=?Negate(a);?
  • ????int?result;?
  • ????int?sub?=?3?<<?29;?
  • ????int?threes?=?1?<<?29;?
  • ????result?=?0;?
  • ????while?(threes?>?0)?{?
  • ????????if?(a?>=?sub)?{?
  • ????????????a?=?Add(a,?Negate(sub));?
  • ????????????result?=?Add(result,?threes);?
  • ????????}?
  • ????????sub?>>=?1;?
  • ????????threes?>>=?1;?
  • ????}?
  • ????if?(negative)?result?=?Negate(result);?
  • ????return?result;?
  • }?
  • public?static?int?Negate(int?a)?{?
  • ????return?Add(~a,?1);?
  • }?
  • public?static?int?Add(int?a,?int?b)?{?
  • ????int?x?=?0;?
  • ????x?=?a?^?b;?
  • ????while?((a?&?b)?!=?0)?{?
  • ????????b?=?(a?&?b)?<<?1;?
  • ????????a?=?x;?
  • ????????x?=?a?^?b;?
  • ????}?
  • ????return?x;?
  • }?
  • 注:本例是C#實(shí)現(xiàn),因?yàn)樽髡吒煜#,但本題更傾向于算法,所以語(yǔ)言并不是太重要吧?(當(dāng)然只是在不使用語(yǔ)言特性的前提下。)

    如果你還想了解更多的方法可以點(diǎn)擊這里。


    總結(jié)

    以上是生活随笔為你收集整理的[算法]不使用*、/、+、-、%操作符求一个数的1/3的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。