幀同步之:定點數原理、運算、實現

幀同步之:定點數原理、運算、實現

簡述

  • 定點數:小數點固定的數
  • 浮點數:小數點不固定的數

一些背景知識

  • 本文假設你擁有計算機組成原理中有關二進制、操作符、位運算的相關知識
// 左移操作時將運算數的二進制碼整體左移指定位數,左移之後的空位用0補充
// 右移操作是將運算數的二進制碼整體右移指定位數,右移之後的空位用符號位補充,如果是正數用0補充,負數用1補充
// 負數,計算機中使用補碼的方式表示
// 補碼 = ~原碼 + 1
// -1的碼:~(10000000 00000000 00000000 00000001) + 1 => 01111111 11111111 11111111 11111110 + 1

定點數和浮點數比較

  • 性能:定點數 > 浮點數,根據我的測試結果,c#中4到5倍的性能差距
  • 範圍:定點數 < 浮點數,根據需要控制小數位,比如我使用16位小數位,有一位符號位,那麼範圍是(負2的47次方, 正2的47次方-1)
  • 一致性:定點數不同平臺運算結果一致,浮點數不同平臺運算結果可能不同

定點數表示

  • 根據需要使用32位或者64位整形表示

定點數原理

  • 使用整形數中的一部分bit位作爲整數部分,剩下的作爲小數部分

實現

class FixVal{

    const int total_bit_cnt = 64;
    
    const int f_bit_cnt = 16;

    const int i_bit_cnt = total_bit_cnt - f_bit_cnt;

    const long f_mask = (long)(ulong.MaxValue >> i_bit_cnt);

    const long i_mask = (long)(-1L & ~f_mask);

    const long f_range = f_mask + 1;

    public const long min_val = long.MinValue >> f_bit_cnt;
    public const long max_val = long.MaxValue >> f_bit_cnt;

    long mRaw;

    public FixVal(int intVal):this(((long)intVal) << f_bit_cnt){
        
    }

    public FixVal(long raw){
        mRaw = raw;
    }

    public long GetRaw(){
        return mRaw;
    }

    public static FixVal operator +(FixVal a, FixVal b){
        return new FixVal(a.mRaw + b.mRaw);
    }

    public static FixVal operator -(FixVal a, FixVal b){
        return new FixVal(a.mRaw - b.mRaw);
    }

    public static FixVal operator *(FixVal a, FixVal b){
        return new FixVal((a.mRaw * b.mRaw + (f_range >> 1)) >> f_bit_cnt);
    }

    public static FixVal operator /(FixVal a, FixVal b){
        return new FixVal((a.mRaw << f_bit_cnt) / b.mRaw);
    }

    public static explicit operator double (FixVal fixVal){
        return (double)(fixVal.mRaw >> f_bit_cnt) + (fixVal.mRaw & f_mask) / (double)f_range;
    }

}

測試結果

  • 測試代碼
FixVal a = new FixVal(35532);
FixVal b = new FixVal(5);
FixVal c = a / b;
Console.WriteLine(c.GetRaw());
double d = (double)c;
Console.WriteLine(d);
Console.WriteLine(35532f / 5f);
  • 輸出
465725030
7106.39999389648
7106.4

小結

  • 頂點數提供了一種高性能的可用於幀同步中保障多平臺計算結果一致性的方案
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章