使用按位运算截取数字的最后两位。

4

我有一个整数n,我想使用位运算仅截断数字的最后两位。

因此,在常规算术中,它很简单,只需n /= 100。但是如何使用位运算完成呢?

谢谢,

(顺便说一下,这是在C++中)

[编辑]:例如,给定数字1234,我想获得12。(删除最后两个数字34

[Edit2:]让我重新表达问题。我试图理解为什么特定函数在给定负输入时截断数字的最后两位会出现问题。(我没有这个函数的代码)

以下是一组输入及其相应的输出

-200901 ==> 186113241

-200801 ==> 186113242

-200701 ==> 186113243

-200601 ==> 186113244

-190001 ==> 186113350

-190101 ==> 186113349

-190201 ==> 186113348

-190301 ==> 186113347


1
你是想把数字1234变成数字12吗?还是想从数字1234中取出数字34?或者是想把1234变成1200?(我认为你是想把它变成12,但是想确认一下)。 - SirPentor
5
n /= 100 有什么问题? - Jeffrey
按位运算是在2的幂上工作的。在10的幂上工作将会非常困难、不方便,甚至有可能根本不可能。 - Louis Wasserman
1
如果是Java,你总是可以反编译它并查看源代码。 - Mikita Belahlazau
1
这些评论变得越来越长了。考虑使用 [聊天] 链接将对话转移到聊天中。当您开始聊天时,它会自动将评论导入到聊天中,因此您不会失去任何上下文。 - jamesmortensen
显示剩余22条评论
2个回答

1

在这里,您想要除以一个常数:100

根据Suraj Chandran在他的评论中提供的如何仅使用位移和加法进行乘法和除法?

您可以将其重新解释为乘以1/100。

在二进制中, 1/100可以近似为 1/2^7 * (1/2^0 + 1/2^2 + 1/2^6+ 1/2^7+ 1/2^8+ 1/2^9 + 1/2^11+ 1/2^13+ 1/2^14+ 1/2^15+ 1/2^20+ 1/2^22 + 1/2^26 + 1/2^27 + 1/2^28 1/2^29)

所以你用(n >> 0 + n >> 2 + n >> 6 + n >> 7 + n >> 8 + n >> 9 + n >> 11 + n >> 13 + n >> 14 + n >> 15 + n >> 20 + n >> 22 + n >> 26 + n >> 27 + n >> 28 + n >> 29)>>7来进行近似计算。

这是否与您的遗留代码相符?

我不敢说这总是会给出正确的答案,因为我没有仔细审查这些近似的影响,有些情况下可能会存在舍入问题。

在Java代码中,应该是这样:

剩余 = ((n>>0) + (n>>2) + (n>>6) + (n>>7) + (n>>8) + (n>>9) + (n>>11) + (n>>13) + (n>>14) + (n>>15) + (n>>20) + (n>>22) + (n>>26) + (n>>27) + (n>>28) + (n>>29)) >> 7;

http://ideone.com/8UlD7上添加了一个示例。

我找不到用位运算符替换加法的方法,也无法重现您使用负值时的结果。


我不知道。真的。我没有访问代码的权限。但是,如果这对于我列出的负面情况产生相同的输出,那么我想你是正确的~ :) - One Two Three
抱歉,只是想澄清一下。那么在Java代码中,它应该是这样的:n = n >> 7 ^ n >> 9 ^ n >> 13 ^ n >> 14 ^ n >> 15 ^ n >> 16 ^n >> 18 ^ n >> 20 ^ n >> 21 ^ n >> 22 ^ n >> 27 ^ n >> 29;?我尝试了一下,无论将n初始化为什么值,输出总是1976。 - One Two Three
我用Java示例修改了我的答案。仍在研究异或和负面情况。 - Jerome WAGNER
你的代码总是给出比正确结果少1个单位的数字。例如,200901 ===>[你的函数] ===> 2008,但实际上应该是2009 - One Two Three
是的,不总是。你可以尝试使用12345作为例子。这些都是舍入问题。例如,对于200901 => 257150 / 128 => 2008.98;对我的解决方案进行仔细审查以解决舍入问题是必要的。无论如何,我无法复现你在负值上得到的结果。抱歉。 - Jerome WAGNER

0

好的,另一种方法。

1234 : 100 = 12, remainder 34

现在是二进制,希望我没有搞砸:

 100 1101 0010 : 110 0100 = 1100 Result
- 11 0010 0
-----------
   1 1011 00
  -1 1001 00
  ----------
     0010 001
    -       0
    ---------
      010 0010
     -       0
     ---------
       10 0010 remaining

尝试将其转换为算法,这会比x /= 100慢得多,无论你如何做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接