【问题标题】:encode three integers into single integer将三个整数编码为单个整数
【发布时间】:2018-08-09 15:24:32
【问题描述】:

我必须将 3 个数字编码为同一个整数。

我有这 3 个测量值

uint256 carLength;
uint256 carWidth;
uint256 carDepth;

我想将这 3 个数字编码为同一个整数,并可以解码。我的问题是我在这个低级别上不是很有经验。

我想到了这样的功能

function encodeNumbers(uint256 a, uint256 b, uint256 c) public view returns(uint256);

function decodeNumber(uint256) public view returns (uint256, uint256, uint256);

关于如何进行的建议?

【问题讨论】:

  • 为什么要把三个整数合二为一?是为了节省空间和SSTORE的相关gas费用吗?

标签: ethereum solidity smartcontracts


【解决方案1】:

如果您将每个 a,b,c 设为 32 位(4 字节,或大多数语言中的标准 int),您可以通过一些简单的位移来实现。

pragma solidity 0.4.24;

contract Test {
    function encodeNumbers(uint256 a, uint256 b, uint256 c) public view returns(uint256 encoded) {
        encoded |= (a << 64);
        encoded |= (b << 32);
        encoded |= (c);
        return encoded;
    }

    function decodeNumber(uint256 encoded) public view returns (uint256 a, uint256 b, uint256 c) {
        a = encoded >> 64;
        b = (encoded << 192) >> 224;
        c = (encoded << 224) >> 224;
        return;
    }


}

在编码时,我们只是将数字移动到连续的 32 位部分中。解码时,我们做相反的事情。但是,在 b 和 c 的情况下,我们需要先将其他数字消隐,先左移再右移。

uint256,顾名思义,实际上有 256 位,所以如果你真的需要的话,你实际上可以在其中放入 3 个最多 85 位的数字。

【讨论】:

  • 这对负数也有效吗?我正在尝试,但似乎不起作用
  • uint256 是无符号的,它没有负数
  • 如果你想要负数,你需要使用 int256,但是转换有点不同,因为你需要扩展符号。在 Google 和 Stack Overflow 上有大量的 C/C++ 处理示例,同样的概念也适用于这里
  • 如果目标只是在存储值时降低 gas 成本,您可以将它们放入 struct 并让 Solidity 编译器完成工作,例如struct foo { uint8 a; uint8 b; uint8 c; }.
  • @RaghavSood 感谢您分享惊人的意见。您能否指出一些我可以关注负数的资源?我会很感激的。
猜你喜欢
  • 1970-01-01
  • 2017-12-26
  • 2016-11-23
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 2014-10-06
相关资源
最近更新 更多