C 获得二次幂相关结果的优雅方式

C 获得二次幂相关结果的优雅方式,c,C,首先,很抱歉标题含糊不清。我的问题是: 设n>0为自然数。确定正数k,使2^i+k=n为最大可能的i 我该如何在C语言中优雅地实现这一点 求2的最大幂小于n。(通过四舍五入log2n)调用数字x 要查找的k是n-2^x. 或 您可以编写一个循环,检查小于n的每两次幂 第一种方法更快。(恒定时间vs.O(n)时间)inti=0;j=1,k,n=(你的值); 如果(n>0) { 而(2*j0@Jasen:问题是“正k”,这通常意味着k>=0如果他们想包含0,他们会说非负,0不是正0既不是正也不是负。

首先,很抱歉标题含糊不清。我的问题是:

n>0
为自然数。确定正数
k
,使
2^i+k=n
为最大可能的
i

我该如何在C语言中优雅地实现这一点

  • 求2的最大幂小于n。(通过四舍五入log2n)调用数字x

  • 要查找的
    k
    n-2^x.

  • 您可以编写一个循环,检查小于n的每两次幂

    第一种方法更快。(恒定时间vs.O(n)时间)

    inti=0;j=1,k,n=(你的值);
    如果(n>0)
    {
    而(2*j//取而代之的是旁观者心目中的优雅

    unsigned long find_remnant(unsigned long n) {
      for (unsigned long j, k = 0;
           (j = n&-n) != n;
           n -= j, k += j ) {
      }
      return k;
    }
    
    这是基于这样一个事实,
    n&-n
    是n的二进制表示中的最低阶
    1
    位。所以循环从n中剥离出一个位,一次一个,在k中累加,直到只剩下一个位,必须是2^i

    由于循环在
    n
    中每设置一位执行一次,而不是在
    n
    中每一位执行一次,因此它可能会更快

    如果是问题,因为
    0&-0
    是0,如果使用
    0
    参数调用(与问题规范相反),函数将简单地返回
    0
    ,这不是不合理的结果

    unsigned long fn(unsigned long n){
    
    unsigned long fn(unsigned long n) {
        int x;
        frexp(n, &x);
        return n - (1UL << (x-1)); }
    
    int x; frexp(n和x);
    返回n-(1UL 0

    您的意思是我们如何在C中优雅地完成它?;)请详细说明您的问题或至少做一个示例。这看起来像一个微不足道的赋值问题。为了您自己的利益,您应该自己解决它。C中只有少数运算符…k=n-2^层(Log2(n))为什么int大写?在执行log2之前忘记减去1--k必须为正“第一种方法更快”-这有点盲目。好的,我会做一些更正。谢谢@Jasen@TheParamagneticCroissant@参数化牛角面包,好的,只是增加了一些理由。你就快到了,这个问题需要k>0@Jasen:问题是“正k”,这通常意味着k>=0如果他们想包含0,他们会说非负,0不是正0既不是正也不是负。
    unsigned long fn(unsigned long n) {
        int x;
        frexp(n, &x);
        return n - (1UL << (x-1)); }