Solidity

如何設置定點數?

  • January 21, 2022

假設我有一個帶符號的 64.64 定點數184448993993021800000.9999浮點表示法。如何定義一個函式來定義一個floor有符號的 64.64 定點數?ceil``int128

function floor(int128) returns(int128);
function ceil(int128) returns(int128);

floor(18444899399302180000) == 0 // floor(0.9999) == 0
floor(-18444899399302180000) == 0 // floor(-0.9999) == -1

ceil(18444899399302180000) == 18446744073709551616 // ceil(0.9999) == 1
ceil(-18444899399302180000) == 0 // ceil(-0.9999) == 0

順便說一句,我正在使用ABDKMath64x64處理帶符號的 64.64 定點數。

我設法實現了兩者floorceil如下所示。該ABDKMath64x64.toInt函式本質上是有符號定點數到有符號整數,因此以下情況成立:

  • toInt(-18444899399302180000) == -1即地板(-0.9999)== -1
  • toInt(0) == 0即地板(0)== 0
  • toInt(18444899399302180000) == 0即地板(0.9999)== 0
  • toInt(18446744073709551616) == 1即地板(1)== 1
  • toInt(-18446744073709551616) == -1即地板(-1)== -1

所以所需要的只是將得到的整數結果轉換回有符號的定點數。

因為ceil我首先檢查帶符號的定點數是否是 %(mod) 乘以 1(unity) 的整數,如果是,那麼我只需返回該數字,因為整數的 ceil 就是那個數字。否則,我將定點數帶入其目前實數範圍之上的實數範圍,然後將其下限,因此例如,如果數字是0.9999我將其帶入其 ceil 的範圍,即 [1, 2) 通過添加使它是 1.9999,然後在這種情況下為我們提供 ceil ie 1。因此以下情況成立:

  • ceil(-18444899399302180000) == 0即 ceil (-0.9999) == 0
  • ceil(0) == 0即 ceil (0) == 0
  • ceil(18444899399302180000) == 0即 ceil (0.9999) == 1
  • ceil(18446744073709551616) == 1即 ceil (1) == 1
  • ceil(-18446744073709551616) == -1即 ceil (-1) == -1
pragma solidity ^0.8.0;

import { ABDKMath64x64 } from "./ABDKMath64x64.sol";

contract FloorCeil {

   int128 constant unity = 18446744073709551616;

   function floor(int128 fp) public pure returns(int128) {
       return ABDKMath64x64.fromInt(int256(ABDKMath64x64.toInt(fp)));
   }

   function ceil(int128 fp) public pure returns(int128) {
       if (fp == 0 || fp%unity == 0) {
           return fp;
       }
       return floor(ABDKMath64x64.fromInt(int256(ABDKMath64x64.toInt(ABDKMath64x64.add(fp, unity)))));
   }
}

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