将两个整数作为一个整数传递

发布于 2024-10-12 12:44:22 字数 71 浏览 2 评论 0原文

我有两个整数,我需要传递一个整数,然后取回两个整数的值。

我正在考虑使用逻辑运算符(AND、OR、XOR 等)。

I have two integers that I need to pass through one integer and then get the values of two integers back.

I am thinking of using Logic Operators (AND, OR, XOR, etc) .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

另类 2024-10-19 12:44:22

使用 C 编程语言,假设两个整数小于 65535,可以按如下方式完成。

void take2IntegersAsOne(int x)
{
   // int1 is stored in the bottom half of x, so take just that part.
   int int1 = x & 0xFFFF;  

   // int2 is stored in the top half of x, so slide that part of the number
   // into the bottom half, and take just that part.
   int int2 = (x >> 16) & 0xFFFF

   // use int1 and int2 here. They must both be less than 0xFFFF or 65535 in decimal

}


void pass2()
{
  int int1 = 345;
  int int2 = 2342;
  take2Integers( int1 | (int2 << 16) );
}

这依赖于 C 中整数存储在 4 个字节中的事实。因此,该示例使用前两个字节来存储其中一个整数,使用接下来的两个字节来存储第二个整数。这确实施加了限制,尽管每个整数必须具有足够小的值,以便它们每个都只能容纳 2 个字节。

移位运算符 <<和>>用于上下滑动整数的位。移位 16,将位移动两个字节(因为每个字节有 8 位)。

使用 0xFFFF 表示数字的低两个字节中的所有位均为 1 的位模式 因此,AND 运算(使用 & 运算符)会导致所有不在这两个低字节中的位被关闭(返回到零)。这可用于从当前提取的整数中删除“其他整数”的任何部分。

Using the C programming language, it could be done as follows assuming that the two integers are less than 65535.

void take2IntegersAsOne(int x)
{
   // int1 is stored in the bottom half of x, so take just that part.
   int int1 = x & 0xFFFF;  

   // int2 is stored in the top half of x, so slide that part of the number
   // into the bottom half, and take just that part.
   int int2 = (x >> 16) & 0xFFFF

   // use int1 and int2 here. They must both be less than 0xFFFF or 65535 in decimal

}


void pass2()
{
  int int1 = 345;
  int int2 = 2342;
  take2Integers( int1 | (int2 << 16) );
}

This relies on the fact that in C an integer is stored in 4 bytes. So, the example uses the first two bytes to store one of the integers, and the next two bytes for the second. This does impose the limit though that each of the integers must have a small enough value so that they will each fit into just 2 bytes.

The shift operators << and >> are used to slide the bits of an integer up and down. Shifting by 16, moves the bits by two bytes (as there are 8 bits per byte).

Using 0xFFFF represents the bit pattern where all of the bits in the lower two bytes of the number are 1s So, ANDing (with with & operator) causes all the bits that are not in these bottom two bytes to be switched off (back to zero). This can be used to remove any parts of the 'other integer' from the one you're currently extracting.

强辩 2024-10-19 12:44:22

这个问题有两个部分。首先,如何将两个 32 位整数位掩码为 64 位长整数?

正如其他人所说,假设我有一个函数,它接受 X 和 Y 坐标,并返回一个代表该点线性的 longint价值。我倾向于将这种方式称为二维数据的线性化:

public long asLong(int x, int y) {
    return ( ((long)x) << 32 ) | y;
}

public int getX(long location) {
    return (int)((location >> 32) & 0xFFFFFFFF);
}

public int getY(long location) {
    return (int)(location & 0xFFFFFFFF);
}

请原谅我对操作顺序的偏执,有时其他操作比 << 更贪婪,导致事情比应有的情况移动得更远。

为什么这有效?什么时候会失败?
整数往往恰好是长整型大小的一半,这很方便。我们正在做的是将 x 转换为 long,将其向左移动,直到它完全位于 y 的左侧,然后执行并集运算 (OR) 将两者的位组合起来。

让我们假设它们是 4 位数字组合成 8 位数字:

x = 14     :      1110
y =  5     :      0101

x = x << 4 : 1110 0000

p = x | y  : 1110 0000
           OR     0101
             ---------
             1110 0101

同时,相反:

p = 229    : 1110 0101  
x = p >> 4 : 1111 1110  //depending on your language and data type, sign extension
                        //can cause the bits to smear on the left side as they're
                        //shifted, as shown here. Doesn't happen in unsigned types
x = x & 0xF:
             1111 1110
         AND 0000 1111
         -------------
             0000 1110  //AND selects only the bits we have in common

y = p & 0xF:
             1110 0101
         AND 0000 1111
         -------------
             0000 0101  //AND strikes again

这种方法很久以前就出现了,在需要从存储或传输空间中挤出每一位的环境中。如果您不在嵌入式系统上或立即打包这些数据以便通过网络传输,则整个过程的实用性很快就会开始崩溃:

  • 仅装箱几乎总是立即需要的返回值就需要太多工作。拆箱并由呼叫者阅读。这有点像挖了一个洞然后把它填上。
  • 它大大降低了代码的可读性。 “返回什么类型?”呃...一个 int...和另一个 int...长整型。
  • 它可能会引入难以追踪的错误。例如,如果您使用无符号类型并忽略符号扩展,则稍后会迁移到导致这些类型采用二进制补码的平台。如果您保存了 longint,并尝试稍后在代码的另一部分中读取它,则可能会在位移位上遇到差一错误,并花费一个小时调试您的函数,结果却发现是参数错误。

如果真的很糟糕,还有什么替代方案?

这就是人们询问您的语言问题的原因。理想情况下,如果您使用的是 C 或 C++ 之类的语言,最好这样说。

struct Point { int x; int y; };

public Point getPosition() {
    struct Point result = { 14,5 };
    return result;
}

否则,在 Java 等 HLL 中,您可能会使用内部类来实现相同的功能:

public class Example {
    public class Point {
        public int x;
        public int y;
        public Point(int x, int y) { this.x=x; this.y=y; }
    }

    public Point getPosition() {
        return new Point(14,5);
    }
}

在这种情况下,getPosition 返回一个示例。 Point - 如果您经常使用 Point,请将其提升为自己的完整类别。事实上,java.awt 已经有几个 Point 类,包括 Point 和 Point.Float

最后,许多现代语言现在都有语法糖,用于将多个值装箱到元组中或直接从函数返回多个值。这是最后的手段。根据我的经验,任何时候你假装数据不是它本来的样子,你最终都会遇到问题。但是,如果您的方法绝对必须返回两个实际上根本不属于同一数据的数字,则元组或数组就是最佳选择。

C++ stdlib 元组的参考可以在以下位置找到
http://www.cplusplus.com/reference/std/tuple/

There are two parts to this question. First, how do you bitmask two 32-bit Integers into a 64-bit Long Integer?

As others have stated, let's say I have a function that takes an X and Y coordinate, and returns a longint representing that Point's linear value. I tend to call this linearization of 2d data:

public long asLong(int x, int y) {
    return ( ((long)x) << 32 ) | y;
}

public int getX(long location) {
    return (int)((location >> 32) & 0xFFFFFFFF);
}

public int getY(long location) {
    return (int)(location & 0xFFFFFFFF);
}

Forgive me if I'm paranoid about order of operations, sometimes other operations are greedier than <<, causing things to shift further than they should.

Why does this work? When might it fail?
It's convenient that integers tend to be exactly half the size of longints. What we're doing is casting x to a long, shifting it left until it sits entirely to the left of y, and then doing a union operation (OR) to combine the bits of both.

Let's pretend they're 4-bit numbers being combined into an 8-bit number:

x = 14     :      1110
y =  5     :      0101

x = x << 4 : 1110 0000

p = x | y  : 1110 0000
           OR     0101
             ---------
             1110 0101

Meanwhile, the reverse:

p = 229    : 1110 0101  
x = p >> 4 : 1111 1110  //depending on your language and data type, sign extension
                        //can cause the bits to smear on the left side as they're
                        //shifted, as shown here. Doesn't happen in unsigned types
x = x & 0xF:
             1111 1110
         AND 0000 1111
         -------------
             0000 1110  //AND selects only the bits we have in common

y = p & 0xF:
             1110 0101
         AND 0000 1111
         -------------
             0000 0101  //AND strikes again

This sort of approach came into being a long time ago, in environments that needed to squeeze every bit out of their storage or transmission space. If you're not on an embedded system or immediately packing this data for transmission over a network, the practicality of this whole procedure starts to break down really rapidly:

  • It's way too much work just for boxing a return value that almost always immediately needs to be unboxed and read by the caller. That's kind of like digging a hole and then filling it in.
  • It greatly reduces your code readability. "What type is returned?" Uh... an int.. and another int... in a long.
  • It can introduce hard-to-trace bugs down the line. For instance, if you use unsigned types and ignore the sign extension, then later on migrate to a platform that causes those types to go two's complement. If you save off the longint, and try to read it later in another part of your code, you might hit an off-by-one error on the bitshift and spend an hour debugging your function only to find out it's the parameter that's wrong.

If it's so bad, what are the alternatives?

This is why people were asking you about your language. Ideally, if you're in something like C or C++, it'd be best to say

struct Point { int x; int y; };

public Point getPosition() {
    struct Point result = { 14,5 };
    return result;
}

Otherwise, in HLLs like Java, you might wind up with an inner class to achieve the same functionality:

public class Example {
    public class Point {
        public int x;
        public int y;
        public Point(int x, int y) { this.x=x; this.y=y; }
    }

    public Point getPosition() {
        return new Point(14,5);
    }
}

In this case, getPosition returns an Example.Point - if you keep using Point often, promote it to a full class of its own. In fact, java.awt has several Point classes already, including Point and Point.Float

Finally, many modern languages now have syntactic sugar for either boxing multiple values into tuples or directly returning multiple values from a function. This is kind of a last resort. In my experience, any time you pretend that data isn't what it is, you wind up with problems down the line. But if your method absolutely must return two numbers that really aren't part of the same data at all, tuples or arrays are the way to go.

The reference for the c++ stdlib tuple can be found at
http://www.cplusplus.com/reference/std/tuple/

黄昏下泛黄的笔记 2024-10-19 12:44:22

嗯.. @Felice 是对的,但如果它们都适合 16 位,就有一种方法:

output_int = (first_int << 16) | second_int
                               ^
                           means 'or'

打包它们,然后

first_int = output_int & 0xffff
second_int = (output int >> 16) & 0xffff
                                ^
                           means 'and'

提取它们。

Well.. @Felice is right, but if they both fit in 16 bit there's a way:

output_int = (first_int << 16) | second_int
                               ^
                           means 'or'

to pack them, and

first_int = output_int & 0xffff
second_int = (output int >> 16) & 0xffff
                                ^
                           means 'and'

to extract them.

梦在深巷 2024-10-19 12:44:22

两个整数无法容纳一个整数,或者至少无法取回原来的两个整数。
但无论如何,如果两个原始整数仅限于一定数量的位数,您可以(以伪代码形式):
第一个整数
或与
(第二个整数 SHIFTLEFT(nOfBits))

用于取回两个整数
用 nOfBitsOne 表示的二进制数字掩码合并的整数,然后获得第一个整数,然后
将合并的整数右移 nOfBits,就可以得到第二个了。

Two integer can't fit one integer, or at least you cant get back the two original one.
But anyway, if the two original integer are bounded to a sure number of bits you can ( in pseudocode ):
First integer
OR with
(Second integer SHIFTLEFT(nOfBits))

for getting back the two integer
mask the merged integer with a number that is binary represented by nOfBitsOne and you obtain the first integer, then
ShiftRight by nOfBits the merged integer, and you have back the second.

一片旧的回忆 2024-10-19 12:44:22

您可以在 32 位整数中存储 2 个 16 位整数。第一个是前 16 位,第二个是后 16 位。要检索和组合值,请使用移位运算符。

You could store 2 16-bit integers within a 32-bit integer. First one i 16 first bits and second one in the last 16 bits. To retrieve and compose the value you use shift-operators.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文