Unity/C# 中出现不寻常的浮点舍入错误?

An unusual floating point rounding error in Unity/C#?

我正在使用 Unity Asset Store 中名为 World Map Strategy Kit 的资产来开发棋盘游戏。该工具包使用 Vector2 的列表,其值范围从 -0.5 到 +0.5 来确定我地图上 provinces/countries 的边界。

我正在努力读取 SVG 路径并将它们转换为 WMSK 输入的点列表。

基本上,没有给你我整个 40 行的解析方法,我有如下设置:

string raw = "1213.6788";
float x = float.Parse(raw);
float y = float.Parse(raw);
Vector2 a = new Vector2 (x, y);
Debug.Log(a);

它始终将结果四舍五入为 1213.7。

起初我认为这可能只是 float 的 Parse 方法的一个怪癖,所以我写了一个如下所示的改编版本:

string raw = "1213.6788";
float x = (float)double.Parse(raw);
float y = (float)double.Parse(raw);
Vector2 a = new Vector2 (x, y);
Debug.Log(a);

同样的事情。它四舍五入到最接近的十分之一。

我注意到以下类似内容:

string rawX = "1213.6788";
string rawY = "891.7";
float x = (float)double.Parse(raw);
float y = (float)double.Parse(raw);
Vector2 a = new Vector2 (x, y);
int tw = 2500;
int th = 1250;
Vector2 translated = new Vector2 ();
translated.x = (a.x - tw * 0.5f + 0.5f) / tw;
translated.x = (a.y - th * 0.5f + 0.5f) / th;
Debug.Log(a);

现在的输出是: (0.0, 0.2)

再次将其四舍五入到最接近的十分之一。我可以接受一定程度的不准确,但这根本无法接受——我正在尝试将坐标从 2500×1250 坐标系转换为 1×1 坐标系,范围从 -0.5 到 +0.5。我希望大多数坐标需要 3-5 个小数点的信息才能正确存储它。

在我使用过的任何编程语言中——甚至 Java——都定期且始终如一地四舍五入到最接近的十分之一的浮点数。根据我的经验,这不是他们通常做的事情。

所以问题是:我做错了什么?我的意思是,当然可以将信息解析为浮点数,而不会丢失我几乎所有的信息小数位?

它会不会是我的电脑(我有一台相对较弱和陈旧的笔记本电脑,1 GHz Intel CPU 和 2 GB 内存,从 2010 年开始 -- 是的,我知道我需要升级)?

或者它是特定于 Unity 的?会不会是Vector2数据结构造成的损失?

Unity 的默认 VectorX.ToString()(在转换为文本以在您的 Debug.Log() 调用中显示时使用)使用十分之一作为最大精度。

要获得更高的精度,只需使用自定义格式调用 .ToString():例如,要以千位精度显示,请使用 Debug.Log(yourVectorX.ToString("F4"));

注意:基础值应该是正确的;它只是在文本中显示为圆