Solidity

為什麼除法時必須在數字周圍包裹一個 uint() 並且有提示?

  • August 17, 2021

為什麼除法時必須在數字周圍包裹一個 uint() 並且有提示?

當我按照下面的程式碼顯示時,我沒有收到任何錯誤,並且程式碼工作正常。

function doMath() public pure returns(uint256){
   return 100/2;
}

但是當我按照下面的程式碼顯示時,我得到一個錯誤:

返回類型rational_const 不能顯式轉換為類型…

function doMath() public pure returns(uint256){
   return 100/3;
}

uint(100)我知道如果我像這樣包裝兩者,錯誤就會消失uint(3)。但我的問題是為什麼我需要將它們包裝起來uint()以使編譯器不拋出錯誤?

這是一個非常好的問題。它涉及一個可能不太為人所知的細節,即使它已記錄在案(Rational 和 Integer Literals):

數字文字表達式保持任意精度,直到它們被轉換為非文字類型(即通過將它們與非文字表達式一起使用或通過顯式轉換)。這意味著計算不會溢出,除法不會在數字文字表達式中截斷。

例如,雖然中間結果甚至不適合機器字長,但(2**800 + 1) - 2**800結果為常量1(類型為)。uint8此外,.5 * 8結果為整數4(儘管在兩者之間使用了非整數)。

換句話說,文字數字類似於100and3不是uints 或任何其他整數類型。相反,Solidity 為它們提供了一種特殊的內部類型,並且僅使用文字的表達式在編譯時以任意精度進行評估。只有當您分配它們或在具有非文字的表達式中使用它們時,它們才會轉換為實際的整數類型。

另一個重要的事實是,您可以混合使用整數和有理字面量,並且仍然保留這些屬性。so100/3仍然是文字類型 whileuint(100)/3或all 強制轉換100/uint(3)為. 對於,運算符是整數除法,它會默默地丟棄小數部分。uint(100)/uint(3)``uint``uint``/

所以結果uint(100)/uint(3)已經是uint,你可以在沒有額外轉換的情況下返回它。100/3是文字類型,編譯器不會靜默截斷文字。相反,它要求您對uint(ie uint(100/3)) 進行顯式轉換,以表明這確實是您想要發生的事情。不需要它,100/2因為結果是一個不需要截斷的整數文字,編譯器可以將其隱式轉換為uint.

引用自:https://ethereum.stackexchange.com/questions/107287