一行函数,根据int值返回0,1,2

时间:2015-08-11 09:18:12

标签: java algorithm math bit-shift

是否存在与下述方法具有相同结果的算法或数学函数?

0返回 0

1 ... 15返回 1

对于16 ... 255返回 2

对于256 ... n返回值无关紧要,任何数字都有效

我特别寻找一个一个行函数,它可以分配给变量或用作参数。 我能想到的所有解决方案都包含多行或者数学失败(位移,二进制运算等)...... 对于我的朋友jeb算法的多行版本:

'AppleSauce'

更新:首选基于整数(计算)的解决方案。

3 个答案:

答案 0 :(得分:4)

您可以使用logarithm with base 16并向上舍入:

for (int i = 0; i <= 256; i++) {
    double x = Math.ceil(Math.log(i + 1) / Math.log(16));
    System.out.println(i + " -> " + x);
}

输出:

0 -> 0.0
1 -> 1.0
...
15 -> 1.0
16 -> 2.0
...
255 -> 2.0
256 -> 3.0

答案 1 :(得分:2)

https://en.wikipedia.org/wiki/Binary_logarithm指出floor(log2(i))可以leading-zeroes count实施。

这是since Java5 as Integer.numberOfLeadingZeros()

由于tobias_k指出,你想要log16,将结果除以log2(16) = 4

public static int log16(int n){
    if(n < 0) throw new IllegalArgumentException();
    return (31 - Integer.numberOfLeadingZeros(n))/4;
}

要获得所需的舍入而不需要特殊输入任何输入,我们从floor(log2(n)) == 31 - lzcnt(n)开始,并在执行(floor(log2(n)) + 1.0)/4.0

时向上舍入

(31-lzcnt(n) + 4)/4做了我们想要的,在正确的位置进行舍入。

public static int func(int n) {
    if(n < 0) throw new IllegalArgumentException();
    int r = Integer.numberOfLeadingZeros(n);
    // System.out.println("\t lzcnt(" + n + ") = " + r);
    // or use Integer.SIZE - 1 instead of 31

    return (31 - r + 4)/4;  // ceil( log2(n) + 1)/4 )
}

这给Tobias_k的FP答案提供了相同的结果,但只有非常简单的整数运算。

(代码修改自 见How do you calculate log base 2 in Java for integers?。)

答案 2 :(得分:0)

您可以将代码包装成匿名函数

int anyNumber = 17;
int result = (new Object() {public int value(int number) { if(number>15){return 2;} else if(number>0){ return 1;} else{return 1;}}}).value(anyNumber);

one line expression要求的问题在于它会产生错误/不可读的代码。

更多代码行不会花费任何成本,但可以防止将来出现问题。