帧同步--定点数

使用定点数原因

浮点数运算有误差,把浮点数扩大倍数转化为整数进行,保证不同设备上的结果一致 。

定点数放大倍数

放大1024倍:方便使用移位运算放大 缩小
缺点:做乘法 or 除法的时候容易溢出。

定点数乘除运算

乘法:运算结果需要除放大倍数
除法:运算结果需要乘放大倍数

移位操作原理

右移位操作符 >>
(1)如果符号为正,则在高位插入0;
(2)如果符号为负,则在高位插入1;

负数是用补码表示 右移位操作有误差:将负数转正数移位后再转负数
在这里插入图片描述

using System;

namespace PEMath {
    public struct PEInt {
        private long scaledValue;
        public long ScaledValue {
            get {
                return scaledValue;
            }
            set {
                scaledValue = value;
            }
        }
        //移位计数
        const int BIT_MOVE_COUNT = 10;
        const long MULTIPLIER_FACTOR = 1 << BIT_MOVE_COUNT;

        public static readonly PEInt zero = new PEInt(0);
        public static readonly PEInt one = new PEInt(1);


        #region 构造函数
        //内部使用,已经缩放完成的数据
        private PEInt(long scaledValue) {
            this.scaledValue = scaledValue;
        }
        public PEInt(int val) {
            scaledValue = val * MULTIPLIER_FACTOR;
        }
        public PEInt(float val) {
            scaledValue = (long)Math.Round(val * MULTIPLIER_FACTOR);
        }
        //float损失精度,必须显式转换
        public static explicit operator PEInt(float f) {
            return new PEInt((long)Math.Round(f * MULTIPLIER_FACTOR));
        }
        //int不损失精度,可以隐式转换
        public static implicit operator PEInt(int i) {
            return new PEInt(i);
        }
        #endregion

        #region 运算符
        //加,减,乘,除,取反
        public static PEInt operator +(PEInt a, PEInt b) {
            return new PEInt(a.scaledValue + b.scaledValue);
        }
        public static PEInt operator -(PEInt a, PEInt b) {
            return new PEInt(a.scaledValue - b.scaledValue);
        }
        public static PEInt operator *(PEInt a, PEInt b) {
            long value = a.scaledValue * b.scaledValue;
            if(value >= 0) {
                value >>= BIT_MOVE_COUNT;
            }
            else {
                value = -(-value >> BIT_MOVE_COUNT);
            }
            return new PEInt(value);
        }
        public static PEInt operator /(PEInt a, PEInt b) {
            if(b.scaledValue == 0) {
                throw new Exception();
            }
            return new PEInt((a.scaledValue << BIT_MOVE_COUNT) / b.scaledValue);
        }
        public static PEInt operator -(PEInt value) {
            return new PEInt(-value.scaledValue);
        }
        public static bool operator ==(PEInt a, PEInt b) {
            return a.scaledValue == b.scaledValue;
        }
        public static bool operator !=(PEInt a, PEInt b) {
            return a.scaledValue != b.scaledValue;
        }
        public static bool operator >(PEInt a, PEInt b) {
            return a.scaledValue > b.scaledValue;
        }
        public static bool operator <(PEInt a, PEInt b) {
            return a.scaledValue < b.scaledValue;
        }
        public static bool operator >=(PEInt a, PEInt b) {
            return a.scaledValue >= b.scaledValue;
        }
        public static bool operator <=(PEInt a, PEInt b) {
            return a.scaledValue <= b.scaledValue;
        }

        public static PEInt operator >>(PEInt value, int moveCount) {
            if(value.scaledValue >= 0) {
                return new PEInt(value.scaledValue >> moveCount);
            }
            else {
                return new PEInt(-(-value.scaledValue >> moveCount));
            }
        }
        public static PEInt operator <<(PEInt value, int moveCount) {
            return new PEInt(value.scaledValue << moveCount);
        }
        #endregion

        /// <summary>
        /// 转换完成后,不可再参与逻辑运算
        /// </summary>
        public float RawFloat {
            get {
                return scaledValue * 1.0f / MULTIPLIER_FACTOR;
            }
        }

        public int RawInt {
            get {
                if(scaledValue >= 0) {
                    return (int)(scaledValue >> BIT_MOVE_COUNT);
                }
                else {
                    return -(int)(-scaledValue >> BIT_MOVE_COUNT);
                }
            }
        }

        public override bool Equals(object obj) {
            if(obj == null) {
                return false;
            }
            PEInt vInt = (PEInt)obj;
            return scaledValue == vInt.scaledValue;
        }

        public override int GetHashCode() {
            return scaledValue.GetHashCode();
        }

        public override string ToString() {
            return RawFloat.ToString();
        }
    }
}
确定性向量运算
牛顿迭代法求平方根

在这里插入图片描述

public static PEInt Sqrt(PEInt value, int interatorCount = 8) {
            if(value == PEInt.zero) {
                return 0;
            }
            if(value < PEInt.zero) {
                throw new Exception();
            }

            PEInt result = value;
            PEInt history;
            int count = 0;
            do {
                history = result;
                result = (result + value / result) >> 1;
                ++count;
            } while(result != history && count < interatorCount);
            return result;
        }
计算向量夹角

在这里插入图片描述
在这里插入图片描述

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将有符号定点数转换为浮点数,可以按照以下步骤进行: 1. 确定定点数的位数和小数点位置。假设有符号定点数的位数为n,其中m位是小数位,而剩下的n-m位是整数位。在这种情况下,小数点位于第m位。 2. 将有符号定点数表示为二进制形式,并确定其符号位。对于给定的例子-1.25,首先将其转换为二进制形式:-1.25 = -1.01。 3. 确定定点数的符号位。在这种情况下,最左边的位是符号位,0表示正数,1表示负数。 4. 将定点数转换为浮点数。浮点数通常使用IEEE 754标准进行表示。根据该标准,浮点数的表示形式为:(-1)^s × m × 2^e,其中s是符号位,m是尾数(即定点数的小数部分),e是指数。 5. 将定点数转换为尾数(即m)。将定点数的小数部分移动到小数点后面,并将其转换为二进制形式。在这种情况下,尾数m为0.01。 6. 确定指数e。指数e等于小数点右侧的位数(0.01中有两位小数)。根据IEEE 754标准,指数需要加上一个偏移量。对于单精度浮点数,偏移量为127(即2^(k-1)-1,其中k是指数位数)。在这种情况下,指数e等于2(小数点后有两位小数),加上偏移量127,得到e = 129。 7. 确定符号位s。根据定点数的符号位确定浮点数的符号位。在这种情况下,符号位s为1,表示负数。 8. 将上述结果组合起来,得到浮点表示形式为:(-1)^1 × 0.01 × 2^129。 请注意,这是一种简化的解释,并且实际的浮点数转换可能涉及更多的细节和步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值