## Unity net平台的float精度问题 原

梦想游戏人

1.....可以自己实现一套，简单的方案，就是全程用long来运算在需要转换的时候才转换

``````public struct Decimal
{
public const long MaxValue = long.MaxValue;
public const long MinValue = long.MinValue;

//转换规则，用大精度转换为小精度，比如float就用double来转换
//对于乘除来说， 他们之间并不能直接相除 long_a*long_a / split_xxx  才是真正的结果
public const long SPLIT_LONG = 100000;
public const int SPLIT_INT = 100000;
public const float SPLIT_FLOAT = 100000.0f;
public const double SPLIT_DOUBLE = 100000.0;
public long value;
public Decimal(Decimal other)
{
this.value = other.value;
}
public Decimal(long value)
{
this.value = value;// 默认构造不认为是定点 需要手动调用parse
}
public Decimal(double value)
{
this.value = Parse(value);
}
public Decimal(float value)
{
this.value = Parse(value);
}
public Decimal(int value)
{
this.value = Parse(value);
}
public static implicit operator Decimal(float value)
{
return new Decimal(value);
}
public static implicit operator Decimal(double value)
{
return new Decimal(value);
}
public static implicit operator Decimal(int value)
{
return new Decimal(value);
}
public static implicit operator Decimal(long value)
{
return new Decimal(value);
}
public static long Parse(float v)
{
double tmp = v;
return (long)(tmp * SPLIT_DOUBLE);
}
public static long Parse(int v)
{
long tmp = v;
return (long)(tmp * SPLIT_INT);
}
public static long Parse(double v)
{
double tmp = v;
return (long)(tmp * SPLIT_DOUBLE);
}
public static double ToDouble(long v)
{
return (double)v / SPLIT_DOUBLE;
}
public static int ToInt(long v)
{
return (int)(v / SPLIT_LONG);
}
public static double ToFloat(long v)
{
return (float)ToDouble(v);
}
public static double ToDouble(Decimal v)
{
return (double)v.value / SPLIT_DOUBLE;
}
public static int ToInt(Decimal v)
{
return (int)(v.value / SPLIT_LONG);
}
public static double ToFloat(Decimal v)
{
return (float)ToDouble(v);
}
public static Decimal operator *(Decimal x, Decimal y)
{

}
}``````

2.....另外也有一个现成的 用long 的定点数库 Fix64

https://github.com/jjcat/FixedMath.Net/blob/master/Fix64.cs

``````   long xxxx=0 ;

const int FRACTIONAL_PLACES = 32;
const long ONE = 1L << FRACTIONAL_PLACES;
xxxx += ONE * 5;
xxxx += ONE * 2;

Debug.LogError((float)xxxx / ONE + "        " + ONE);``````

``````using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using FixMath.NET;
using System.Runtime.InteropServices;

public class NewBehaviourScript : MonoBehaviour
{

// Use this for initialization
void Start()
{
//   this.GetComponent<Animator>().Play("npc_ani_100011_attack_01");
//  this.GetComponent<Animator>().Play("npc_ani_100011_standby_01");

long xx = 2;
decimal bb = 2;
float ff = 2f;
Fix64 fx = (Fix64)2f;
long dd = 2 * Decimal.SPLIT_LONG;
System.Diagnostics.Stopwatch aa = new System.Diagnostics.Stopwatch();
aa.Stop();
aa.Reset();
aa.Start();
for (int i = 0; i < 999999; i++)
{
xx *= 2;
xx /= 2;
}
Debug.LogError("long time=" + aa.ElapsedMilliseconds + "   " + xx);
aa.Stop();
aa.Reset();
aa.Start();
for (int i = 0; i < 999999; i++)
{
bb *= 2;
bb /= 2;
}
Debug.LogError("decimal time=" + aa.ElapsedMilliseconds);

aa.Stop();
aa.Reset();
aa.Start();
for (int i = 0; i < 999999; i++)
{
ff *= 2f;
ff /= 2f;
}
Debug.LogError("float time=" + aa.ElapsedMilliseconds + "   " + ff);
aa.Stop();
aa.Reset();
aa.Start();
for (int i = 0; i < 999999; i++)
{
fx = Fix64.FastMul((Fix64)2f, fx);
fx /= (Fix64)2f;
}
Debug.LogError("fix64 with float time=" + aa.ElapsedMilliseconds);

Fix64 twof = (Fix64)2f;
aa.Stop();
aa.Reset();
aa.Start();
for (int i = 0; i < 999999; i++)
{
fx = Fix64.FastMul(twof, fx);
fx /= twof;
}
Debug.LogError("fix64 time=" + aa.ElapsedMilliseconds);

aa.Stop();
aa.Reset();
aa.Start();
for (int i = 0; i < 999999; i++)
{
dd *= Decimal.Parse(2f);
dd /= Decimal.Parse(2f);
}
Debug.LogError("light decimal time=" + aa.ElapsedMilliseconds + "   " + Decimal.ToDouble(dd));

/*  long xxxx=0 ;

const int FRACTIONAL_PLACES = 16;
const long ONE = 1L << FRACTIONAL_PLACES;
xxxx += ONE * 5;
xxxx += ONE * 2;

Debug.LogError((float)xxxx / ONE + "        " + ONE  + "   " + ONE*ONE/ONE);*/
}

// Update is called once per frame
void Update()
{

}
}
``````

### 梦想游戏人

Kibana 是一个为 Logstash 和 ElasticSearch 提供的日志分析的 Web 接口。可使用它对日志进行高效的搜索、可视化、分析等各种操作。 环境要求： ruby >= 1.8.7 (probably?) bundler logstash...

2013/02/13
11.7W
1

OpenFeint 关门大吉后，OpenFeint 创始人推出了开源项目 OpenKit。OpenKit 支持Unity 3D游戏引擎，并未 iOS 和 Android 的游戏开发者提供开源 API以及存储、数据同步服务。OpenKit 目前提供對...

2013/03/11
3K
0
Java™ 编译器--Janino

Janino是一个超级小但又超级快的Java™ 编译器. 它不仅能像javac工具那样讲一组源文件编译成字节码文件，还可以对一些Java表达式，代码块，类中的文本(class body)或者内存中源文件进行编译，...

2013/04/02
4.2K
0

Apache VCL 是一个自服务的系统，为最终用户提供专用计算环境的远程访问环境。典型的使用场景是数据中心，也可以是物理刀片服务器、传统机架服务器或者虚拟机。VCL 也可以提供独立机器的代理...

2013/01/04
2.6K
0

Gephi是一款开源的交互式的复杂网络分析平台。它支持Windows, Mac OS X以及Linux等环境。主要功能包括： 网络布局：提供了超过10种不同的布局算法 网络社区分析和分类 网络属性计算 动态网络...

2013/04/22
2.6W
0

Hacker News 简讯 2020-08-15

FalconChen

24
0
OSChina 周六乱弹 —— 老椅小猫秋乡梦 梦里石台堆小鱼

Osc乱弹歌单（2020）请戳（这里） 【今日歌曲】 @小小编辑 ：《MOM》- 蜡笔小心 《MOM》- 蜡笔小心 手机党少年们想听歌，请使劲儿戳（这里） @狄工 ：腾讯又在裁员了，35岁以上清退，抖音看到...

61
1

17
0
Anaconda下安装keras和tensorflow

Anaconda下安装keras和tensorflow 一、下载并安装Anaconda: Anaconda下载 安装步骤： 如果是多用户操作系统选择All Users，单用户选择Just Me 选择合适的安装路径 然后勾选这个，自动配置环境...

Atlantis-Brook

15
0

13
0