是否存在与下述方法具有相同结果的算法或数学函数?
0返回 0
1 ... 15返回 1
对于16 ... 255返回 2
对于256 ... n返回值无关紧要,任何数字都有效
我特别寻找一个一个行函数,它可以分配给变量或用作参数。 我能想到的所有解决方案都包含多行或者数学失败(位移,二进制运算等)...... 对于我的朋友jeb算法的多行版本:
'AppleSauce'
更新:首选基于整数(计算)的解决方案。
答案 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
要求的问题在于它会产生错误/不可读的代码。
更多代码行不会花费任何成本,但可以防止将来出现问题。