欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 【Unity】什么是定点数?定点数的实现原理(个人复习笔记/侵删/不足之处欢迎斧正)

【Unity】什么是定点数?定点数的实现原理(个人复习笔记/侵删/不足之处欢迎斧正)

2024/10/25 23:23:10 来源:https://blog.csdn.net/m0_73952999/article/details/142916175  浏览:    关键词:【Unity】什么是定点数?定点数的实现原理(个人复习笔记/侵删/不足之处欢迎斧正)

什么是定点数?定点数的实现原理

什么是定点数?

约定计算机中小数点的位置,且这个位置固定不变,小数点前、后的数字,分别用二进制表示,然后组合起来就可以把这个数字在计算机中存储起来,这种表示方式叫做「定点」表示法,用这种方法表示的数字叫做「定点数」。

什么是定点数?-CSDN博客

在使用帧同步开发中,如果不使用定点数而采用浮点数,会出现各种而样的问题(浮点误差)

真正使用定点数时,基本保留0位小数,完全使用整形数据,误差最小

定点数实现机制?

1.小数定位法:

        固定浮点数的小数点,比如保留一位保留两位,这样会接近真实值。可以进行加减计算,但是涉及到复杂乘除运算时弊端就会暴露,差生了更多的小数

2.乘法放大入整法:

        通过确定放大因子,然后转为整数,之后计算变为完全整数的运算,最后在渲染层需要渲染时除去放大因子,交由渲染层去渲染。但是细节容易出现疏漏,可能会丢失精度

3.位移运算入整法(推荐):

        位移运算只能用于整型数值,因此比较适合在定点数中,位移运算满足二次幂运算,效率较高,速度快。

        如何实现:提前准备一个放大因子,在非定点数类型转为定点数时,左移放大因子

《帧同步定点数》定点数原理和无损精度的实现方式_帧同步 定点数-CSDN博客

移位运算为什么更快?

因为移位指令占2个机器周期,而乘除法指令占4个机器周期。
计算机cpu的移位指令一般单周期就能执行完毕,而其他的指令比如乘法或除法指令都是多周期指令,所以节省了运行时间,导致效率更高的结果。

注意事项?

定点数转换为浮点数之后,浮点数就不应该再参与到帧同步的运算之中。可以说,帧同步的计算不需要转换为浮点数,只有把结果交给UI表现时,才需要转换为浮点数

VINT

using System;[Serializable]
public struct VInt:IComparable<VInt>
{private long i;//位移计数const int FIX_MULTIPLE = 1024;public static readonly VInt one = new VInt((long)FIX_MULTIPLE);public int Int { get { return (int)i; } }public float RawFloat { get { return (float)this.i * 1.0f / FIX_MULTIPLE; } }public int RawInt { get { return (int)i / FIX_MULTIPLE; } }private VInt(long i){this.i = i;}public VInt(int i){this.i = i * FIX_MULTIPLE;}public VInt(float f){this.i = (int)Math.Round((double)(f * 1.0f * FIX_MULTIPLE));}public override bool Equals(object o){if (o == null){return false;}VInt vInt = (VInt)o;return this.i == vInt.i;}public override int GetHashCode(){return this.i.GetHashCode();}public static VInt Min(VInt a, VInt b){return new VInt(Math.Min(a.i, b.i));}public static VInt Max(VInt a, VInt b){return new VInt(Math.Max(a.i, b.i));}public override string ToString(){return this.RawFloat.ToString();}public int CompareTo(VInt other){return i.CompareTo(other.i);}public static explicit operator VInt(float f){return new VInt((int)Math.Round((double)(f * 1.0f * FIX_MULTIPLE)));}public static implicit operator VInt(int i){return new VInt(i);}public static explicit operator float(VInt ob){return (float)ob.i * 1.0f / FIX_MULTIPLE;}public static explicit operator long(VInt ob){return (long)ob.i;}public static VInt operator +(VInt a, VInt b){return new VInt(a.i + b.i);}public static VInt operator -(VInt a, VInt b){return new VInt(a.i - b.i);}public static VInt operator *(VInt a, VInt b){long value = a.i * b.i;if (value >= 0){value /= FIX_MULTIPLE;}else{value = -(-value / FIX_MULTIPLE);}return new VInt(value);}public static VInt operator /(VInt a, VInt b){return new VInt((a.i * FIX_MULTIPLE / b.i));}public static bool operator ==(VInt a, VInt b){return a.i == b.i;}public static VInt operator -(VInt a){return new VInt(-a.i);}public static bool operator !=(VInt a, VInt b){return a.i != b.i;}public static bool operator >(VInt a, VInt b){return a.i > b.i;}public static bool operator <(VInt a, VInt b){return a.i < b.i;}public static bool operator >=(VInt a, VInt b){return a.i >= b.i;}public static bool operator <=(VInt a, VInt b){return a.i <= b.i;}public static VInt operator >>(VInt value, int moveCount){if (value.i >= 0){return new VInt(value.i >> moveCount);}else{return new VInt(-(-value.i >> moveCount));}}public static VInt operator <<(VInt value, int moveCount){return new VInt(value.i << moveCount);}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com