20

I'm wondering if there's a way to convert a boolean to an int without using if statements (as not to break the pipeline). For example, I could write

int boolToInt( boolean b ){
  if ( b )
    return 1
  return 0

But I'm wondering if there's a way to do it without the if statement, like Python's

bool = True 
num = 1 * ( bool )

I also figure you could do

boolean bool = True;
int myint = Boolean.valueOf( bool ).compareTo( false );

This creates an extra object, though, so it's really wasteful and I found it to be even slower than the if-statement way (which isn't necessarily inefficient, just has the one weakness).

4

12 回答 12

30

除了 if 之外,您不能使用布尔值。但是,这并不意味着在装配级别会有一个分支。

如果您检查该方法的编译代码(顺便说一下,使用return b ? 1 : 0;编译到完全相同的指令),您将看到它不使用跳转:

0x0000000002672580: sub    $0x18,%rsp
0x0000000002672587: mov    %rbp,0x10(%rsp)    ;*synchronization entry
0x000000000267258c: mov    %edx,%eax
0x000000000267258e: add    $0x10,%rsp
0x0000000002672592: pop    %rbp
0x0000000002672593: test   %eax,-0x2542599(%rip)        # 0x0000000000130000
                                                ;   {poll_return}
0x00000000025b2599: retq  

注意:这是在热点服务器 7 上 - 您可能会在不同的 VM 上得到不同的结果。

于 2013-06-01T01:54:34.293 回答
13

使用 ?: 运算符:( b ? 1 : 0 )

于 2013-06-01T01:34:50.243 回答
4

You can use the ternary operator:

return b ? 1 : 0;

If this is considered an "if", and given this is a "puzzle", you could use a map like this:

return new HashMap<Boolean, Integer>() {{
    put(true, 1);
    put(false, 0);
}}.get(b);

Although theoretically the implementation of HashMap doesn't need to use an if, it actually does. Nevertheless, the "if" is not in your code.

Of course to improve performance, you would:

private static Map<Boolean, Integer> map = new HashMap<Boolean, Integer>() {{
    put(true, 1);
    put(false, 0);
}};

Then in the method:

return map.get(b);
于 2013-06-01T01:39:56.533 回答
4

否则,您可以使用Apache Commons BooleanUtils.toInteger方法,它就像一个魅力......

// Converts a boolean to an int specifying the conversion values.    
static int  toInteger(boolean bool, int trueValue, int falseValue)

// Converts a Boolean to an int specifying the conversion values.
static int  toInteger(Boolean bool, int trueValue, int falseValue, int nullValue)
于 2015-07-09T11:32:36.973 回答
2

I found a solution by framework. Use compare for Boolean.

// b = Your boolean result
// v will be 1 if b equals true, otherwise 0
int v = Boolean.compare(b, false);
于 2015-10-09T14:20:28.350 回答
1

I can't say I recommend this. It's both slower than the ternary operator by itself, and it's too clever to be called good programming, but there's this:

-Boolean.FALSE.compareTo(value)

It uses the ternary under the covers (a couple of method calls later), but it's not in your code. To be fair, I would be willing to bet that there's a branch somewhere in the Python execution as well (though I probably only bet a nickel ;) ).

于 2013-06-01T02:02:48.950 回答
1

这不是直接可能的,无论如何在Java中都不是。如果您确实需要避免分支,您可以考虑直接使用intorbyte代替 a 。boolean

在这种情况下, VM 也有可能足够聪明以消除分支(if?:)本身,因为无论如何,它boolean的内部表示很可能是文字 1 或 0。这是一篇关于如何检查为 Oracle JDK 生成的本机机器代码的文章,如果您需要速度,请确保您使用的是“服务器”JVM ,因为它比“客户端”执行更积极的优化。

于 2013-06-01T01:49:51.467 回答
0

由于您不需要 if / else 解决方案,因此您的表达方式很完美,尽管我会稍微更改一下

int myint = Boolean.valueOf( bool ).compareTo( Boolean.FALSE );

不涉及对象创建, Boolean.valueOf(boolean b) 返回 Boolean.TRUE 或 Boolean.FALSE,请参阅 API

于 2013-06-01T02:00:54.230 回答
0

You can try using ternary operator like this

int value = flag ? 1 : 0;
于 2013-06-01T01:36:39.170 回答
0

一个合理的替代方案来避免“如果”:

private static Boolean[] array = {false, true};

int boolToInt( boolean b ){
    return Arrays.binarySearch(array, b);
}

请注意,我认为这是一个“谜题”问题,所以如果我自己编码,我会使用三元......

于 2013-06-01T21:21:39.103 回答
0

如今,jdk 提供了一个有用的 Utils 方法:BooleanUtils.toInteger()

源码中jdk实现的方法一定是高效的:

public static int toInteger(boolean bool) {
    return bool ? 1 : 0;
}

所以,我觉得票数最多的答案非常棒,return bool ? 1 : 0是最佳实践。

要使用的示例代码BooleanUtils如下:

BooleanUtils.toInteger(false);
于 2020-08-07T14:13:03.443 回答
-1
int ansInt = givenBoolean ? 1 : 0;
于 2018-05-28T18:14:58.423 回答