[英]How to convert a SNAPSHOT build number into an integer with 3 digit using js
[英]How to remove the nth hexadecimal digit of a integer number without using Strings?
考虑一个十六进制 integer 值,例如n = 0x12345
,如何通过remove(n, 3)
(big endian) 得到0x1235
作为结果?
对于上面的输入,我认为这可以通过执行一些按位步骤来实现:
partA
= 从索引0
提取部分到targetIndex - 1
(应该返回0x123
);partB
= 从targetIndex + 1
中提取部分到length(value) - 1
( 0x5
);((partA << length(partB) | partB)
,给出0x1235
结果。但是,一旦每个十六进制数字占用 4 个空格,我仍然对如何实现它感到困惑。 另外,我不知道检索数字长度的好方法。
这可以使用字符串轻松完成,但是我需要在数千次迭代的上下文中使用它,并且不认为选择字符串是一个好主意。
那么,什么是没有字符串的删除的好方法?
将使用 10 的操作替换为使用 16 的操作。
使用位运算符:
public class Main {
public static void main(String[] args) {
int n = 0x12345;
int temp = n;
int length = 0;
// Find length
while (temp != 0) {
length++;
temp /= 16;
}
System.out.println("Length of the number: " + length);
// Remove digit at index 3
int m = n;
int index = 3;
for (int i = index + 1; i <= length; i++) {
m /= 16;
}
m *= 1 << ((length - index - 1) << 2);
m += n % (1 << ((length - index - 1) << 2));
System.out.println("The number after removing digit at index " + index + ": 0x" + Integer.toHexString(m));
}
}
Output:
Length of the number: 5
The number after removing digit at index 3: 0x1235
使用Math::pow
:
public class Main {
public static void main(String[] args) {
int n = 0x12345;
int temp = n;
int length = 0;
// Find length
while (temp != 0) {
length++;
temp /= 16;
}
System.out.println("Length of the number: " + length);
// Remove digit at index 3
int m = n;
int index = 3;
for (int i = index + 1; i <= length; i++) {
m /= 16;
}
m *= ((int) (Math.pow(16, length - index - 1)));
m += n % ((int) (Math.pow(16, length - index - 1)));
System.out.println("The number after removing digit at index " + index + ": 0x" + Integer.toHexString(m));
}
}
Output:
Length of the number: 5
The number after removing digit at index 3: 0x1235
JavaScript 版本:
n = parseInt(12345, 16);
temp = n;
length = 0;
// Find length
while (temp != 0) {
length++;
temp = Math.floor(temp / 16);
}
console.log("Length of the number: " + length);
// Remove digit at index 3
m = n;
index = 3;
for (i = index + 1; i <= length; i++) {
m = Math.floor(m / 16);
}
m *= 1 << ((length - index - 1) << 2);
m += n % (1 << ((length - index - 1) << 2));
console.log("The number after removing digit at index " + index + ": 0x" + m.toString(16));
这通过编写一个从右侧移除但调整参数以从左侧移除的方法来工作。 好处是从右侧删除也可以使用。 此方法使用longs
来最大化十六进制值的长度。
long n = 0x12DFABCA12L;
int r = 3;
System.out.println("Supplied value: " + Long.toHexString(n).toUpperCase());
n = removeNthFromTheRight(n, r);
System.out.printf("Counting %d from the right: %X%n", r, n);
n = 0x12DFABCA12L;
n = removeNthFromTheLeft(n, r);
System.out.printf("Counting %d from the left: %X%n", r, n);
印刷
Supplied value: 12DFABCA12
Counting 3 from the right: 12DFABA12
Counting 3 from the left: 12DABCA12
这通过递归地从末尾删除一个数字直到您要删除的那个之前的数字来工作。 然后删除它并通过调用堆栈返回,用原始值重建数字。
此方法从右数。
public static long removeNthFromTheRight(long v, int n) {
if (v <= 0) {
throw new IllegalArgumentException("Not enough digits");
}
// save hex digit
long k = v % 16;
while (n > 0) {
// continue removing digit until one
// before the one you want to remove
return removeNthFromTheRight(v / 16, n - 1) * 16 + k;
}
if (n == 0) {
// and ignore that digit.
v /= 16;
}
return v;
}
此方法从左数起。 它只是调整n
的值,然后调用removeFromTheRight
。
public static long removeNthFromTheLeft(long v, int n) {
ndigits = (67-Long.numberOfLeadingZeros(v))>>2;
// Now just call removeNthFromTheRight with modified paramaters.
return removeNthFromTheRight(v, ndigits - n - 1);
}
这是我的使用位操作和解释的版本。
最高设置位有助于找到掩码的偏移量。 在很long
内,该位是 64 - 前导零的数量。 要得到十六进制位数,必须除以 4。要说明能被 4 整除的数字,除法前必须加 3。 这样就产生了位数:
digits = (67-Long.numberOfLeadingZeros(i))>>2
;
然后需要对其进行调整以掩盖数字的适当部分。
offset = digits-i - 1
m
是屏蔽要删除的数字的掩码。 所以从-1L (all hex 'F')
和右移4*(16-offset)
位开始。 这将产生一个掩码,掩码要删除的数字右侧的所有内容。 注意:如果offset
为0
,则移位运算符将为64
,并且不会移位任何位。 为了适应这一点,移位操作被分解为两个操作。
现在只需屏蔽低位v & m
4
位以消除所需的数字。 (v>>>4)^ ~m
static long remove(long v, int i) {
int offset = ((67 - Long.numberOfLeadingZeros(v))>>2) - i - 1;
long m = (-1L >>> (4*(16 - offset) - 1)) >> 1;
return ((v >>> 4) & ~m) | (v & m);
}
与您描述的想法类似,这可以通过为上部和下部创建一个遮罩,移动上部,然后重新组装来完成。
int remove(int x, int i) {
// create a mask covering the highest 1-bit and all lower bits
int m = x;
m |= (m >>> 1);
m |= (m >>> 2);
m |= (m >>> 4);
m |= (m >>> 8);
m |= (m >>> 16);
// clamp to 4-bit boundary
int l = m & 0x11111110;
m = l - (l >>> 4);
// shift to select relevant position
m >>>= 4 * i;
// assemble result
return ((x & ~(m << 4)) >>> 4) | (x & m);
}
其中">>>" 是一个无符号移位。
需要注意的是,如果 0 表示 32 位字中的最高十六进制数字,与输入无关,这要简单得多:
int remove(int x, int i) {
int m = 0xffffffff >>> (4*i);
return ((x & ~m) >>> 4) | (x & (m >>> 4));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.