Java计算数字范围内的一位

标签 java binary bit

我在计算大量范围内的一位时遇到问题。

所以我必须计算从 1 到 1000 的 eq 数字范围内的一位 这是 4938。

public static long countRangeOneBits(long n){
    long t = 0;
    for (long i = 1; i <= n; i++) {
        long x = i;
        while (x > 0) {
            t += x%2;
            x /= 2;
        }
    }
    return t;
}

好的,这工作正常,但我需要计算范围 1..10^16。首先,java 不会计算那么大的数字,至少对于 long 数据类型是这样。我还有其他选择吗?或者你们对我应该如何解决这个问题有什么建议吗?

| From 1 To        | Total             |
|                1 |                1  |
|               10 |               14  |
|              100 |              319  |
|             1000 |             4938  |
|            10000 |            64613  |
|           100000 |           815030  |
|          1000000 |          9884999  |
|         10000000 |        114434632  |
|        100000000 |       1314447116  |
|       1000000000 |      14846928141  |
|  100000000000000 | 2306412649693200  |
| 1000000000000000 |24784747400675300  |

最佳答案

我猜你需要玩玩 2^n。作为从 0 到 (2^n - 1) = n * 2^(n-1) 的 1 位的总数。

在程序中这就是你想要的

private static long getBits(long l){
        if(l == 0){
            return 0;
        }else if(l == 1){
            return 1;
        }
        boolean isPowerOf2Minus1 = (l & (l+1)) == 0;
        long maxBitNum = Long.highestOneBit(isPowerOf2Minus1 ? l+1 : l);
        int maxBit = Long.numberOfTrailingZeros(maxBitNum);
        if((l & (l+1)) == 0){
            return maxBit * (maxBitNum >> 1);
        }
        long diff = l - maxBitNum;
        return diff + 1 + getBits(maxBitNum - 1) + getBits(diff);
    }

结果如下

                   1 :                    1
                  10 :                   17
                 100 :                  319
                1000 :                 4938
               10000 :                64613
              100000 :               815030
             1000000 :              9884999
            10000000 :            114434632
           100000000 :           1314447116
          1000000000 :          14846928141
         10000000000 :         164293127179
        100000000000 :        1809725656079
       1000000000000 :       19809942118413
      10000000000000 :      214309466746894
     100000000000000 :     2306412649693201
    1000000000000000 :    24784747400675348
   10000000000000000 :   264286863212871700
  100000000000000000 :  2804216299269586964

关于Java计算数字范围内的一位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20860490/

相关文章:

用于从本地系统搜索所有 .doc 和 .docx 文件的 java 代码

c# - 'remap' 一个简单的二进制掩码的最佳方法?

python - 如何 `pause` 和 `resume` 下载工作?

c++ - 完美实现按位非(~)运算符(翻转位)

python - Numpy:检查数组中的某个位是否设置为 1 或 0?

xor - 找到不同的最右边的位

java - 类中的枚举助手 (Java)

java - 无法使用 preparedStatement 创建表

java - 启动适用于 Web 开发人员的 Eclipse Java EE IDE 时出错

从 4 2 位创建一个字节(8 位)