在C++中使用java的困惑
我需要用Java翻译这行代码,我 不确定如何处理ptrdiff\t。不确定它在这里做什么。顺便说一下,遮罩块 类型为大小\u t
size_t lowest_bit = mask_block & (-(ptrdiff_t)mask_block);
谢谢
你可以在下面搜索框中键入要查询的问题!
我需要用Java翻译这行代码,我 不确定如何处理ptrdiff\t。不确定它在这里做什么。顺便说一下,遮罩块 类型为大小\u t
size_t lowest_bit = mask_block & (-(ptrdiff_t)mask_block);
谢谢
# 1 楼答案
当心!这有点神奇
( x & ~(x-1) )
返回表达式中的最低设置位。原始代码的作者决定使用( x & (-x) )
,由于整数的two's comlement表示,这实际上是相同的。但是(原作者认为)要获得-x
,需要使用有符号类型,正如前面指出的,ptrdiff_t
是有符号的,size_t
是无符号的由于Java没有无符号类型,
mask_block
将是int
,mask_block & (-mask_block)
将毫无问题地工作注意到,由于有符号和无符号类型之间的互操作性,在C++中,CAST也是多余的。p>
# 2 楼答案
ptrdiff_t
是类型的名称,如int
或::std::string
。C++标准承诺,这种类型将是一个整数类型,足以容纳任何两个指针之间的差异。当然,减法指针在Java中是一个相当陌生的概念。为了做到这一点,ptrdiff_t
必须能够容纳负数使用
ptrdiff_t
的子表达式是一个cast表达式,类似于Java类型转换。但是,与java类型转换不同,C++的CAST表达式更危险更丑陋。它们可以用于Java不愿意进行的各种不同类型的转换。有时它们会产生令人惊讶的结果在本例中,似乎有人需要某种类型的无符号整数(可能是
unsigned long
或其他什么)的值才能为负。他们需要把它转换成一个有符号的值ptrdiff_t
通常是平台支持的最大整数。因此,如果要将任意无符号整数类型转换为有符号整数类型,ptrdiff_t
将是最不可能使用C++相当丑陋的强制转换操作导致某种奇数截断或符号更改的类型特别是,他们想要的类型是^ {CD9>},这是C++标准中的另一种类型。它是一个无符号类型(就像我猜的那样),并且保证是一个整数类型,它的大小足以容纳内存中任何可能对象的大小。它的大小通常与
ptrdiff_t
相同编写代码的人之所以想这样做,是因为有一个有趣的位操纵技巧。为了向你们展示这个技巧,我将向你们展示这个表达式在许多场景中的表现
假设
mask_block
是48。假设在这个假设的平台上,size_t
是16位(非常小,但这只是一个例子)。在二进制中,mask_block
如下所示:和
-(ptrdiff_t)mask_block
是-48,看起来像这样:所以,
48 & -48
是这样的:这是16。请注意,这是48中最低设置位的值。让我们试试50。50看起来像这样:
而-50看起来像这样:
所以,
50 & -50
看起来像这样:也就是2。请再次注意,这是50中最低设定位的值
所以这只是一个在
mask
中找到最低设置位值的技巧。变量名为lowest_bit
这一事实应该是一个线索。:-)当然,这个技巧并不是完全可移植的。C和(也许C++现在运行)的一些平台不使用两个补充表示,并且这个技巧在这些平台上不起作用。p>
在Java中,你可以这样做
long lowest_bit = mask_block & -mask_block;
并获得同样的效果。Java保证两个补码整数,甚至没有无符号整数。所以它应该可以正常工作# 3 楼答案
x & -x
是一种位攻击,清除x
的所有位,不包括其最低位对于
x
的所有非零值,它是1 << lb
,其中lb
是最低有效位的位置(从0开始计数)为什么它被铸造成} 保证是有符号整数类型,^{} 始终是无符号整数类型。因此,我想C++代码的作者希望确保它是签名的,并且具有与指针相同的大小。只需忽略强制转换,就足以将代码移植到Java,因为在Java中,所有整数都是有符号的
<> >所产生的代码也比原来的C/C++版本更便携,它假定机器使用2's complement表示整数,尽管它(至少在理论上)不是由C或C++标准保证的。然而,在Java中,JVM必须使用2的补码ptrdiff_t
?没有进一步的了解,很难说。我甚至不确定是否需要演员阵容^{# 4 楼答案
ptrdiff_t
是应该用于两个指针之间的(整数)差的类型。也就是说,从一个指针减去另一个指针的结果。它是一个带符号的整数,应该足够大,可以选择最大可能数组的大小(所以在Java中,我猜这只是一个int
)