我写了一份合同来理解将变量转换为uint16和uint32的区别。守则如下:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
contract Learning{
bytes8 theKey = 0x3fcb875f0000ddc4;
function cast32() public view returns (uint32) {
return uint32(uint64(theKey));
}
function cast16() public view returns (uint16) {
return uint16(uint64(theKey));
}
}在调用cast32()和cast16()之后,我收到了类似的答案,这两种答案都是56772。为什么当我使用不同的uint,即uint16和uint32时,它给出了类似的答案?
发布于 2022-09-08 15:02:43
我对此有个解释。
注意,theKey的最后四个字节是0000ddc4。因此,我们看到,我们有2个字节空(0000)和2个字节与数据(ddc4)。32位数字是4字节.16位数字是2字节.因此,当您将0x3fcb875f_0000ddc4转换为uint16时,您是在复制ddc4。当您将其转换为uint32时,您正在复制0000ddc4,而且由于前两个字节没有任何值,所以两者都是ddc4。如果我们把ddc4转换成十进制,那就是56772。检查这里:https://www.rapidtables.com/convert/number/hex-to-decimal.html
我创建了2个掩码值来复制最后32位(4字节)的数字和16位(2字节)的相同数字。我创建了函数getLast16Bits和getLast32Bits,它们都产生了相同的结果。
如果在这些空字节中放入更多的值,则结果将有所不同。
例如,给定:0x3fcb875faaffddc4,结果将是65535用于uint16强制转换,4294967295用于uint32强制转换。
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
contract Learning {
uint32 public mask32 = 0x000000000000000000000000ffffffff;
uint16 public mask16 = 0x0000000000000000000000000000ffff;
bytes8 public theKey = 0x3fcb875f_0000ddc4;
uint64 public theKey64 = uint64(theKey);
function getLast16Bits() public view returns(uint) {
return theKey64 & mask16;
}
function getLast32Bits() public view returns(uint) {
return theKey64 & mask32;
}
function cast32() public view returns (uint32) {
return uint32(uint64(theKey));
}
function cast16() public view returns (uint16) {
return uint16(uint32(uint64(theKey)));
}
}发布于 2022-09-08 09:55:17
适合于uint16的最大数目是2**16 - 1 = 65535。
由于您的数字小于该值,所以uint16不会被截断。
https://ethereum.stackexchange.com/questions/135230
复制相似问题