我正在做一个Unity项目,需要将UTM坐标转换为纬度和经度。我已经尝试了几种C#解决方案,但是它们都不足够准确。但是我发现了一些Javascript代码,可以给出我想要的确切结果(https://www.movable-type.co.uk/scripts/latlong-utm-mgrs.html)。问题是,当我将代码转换为C#时,它给出了不同的结果。这是我看到问题的代码片段:
Javascript:
var a = 6378137;
var f = 1/298.257223563;
var e = Math.sqrt(f*(2-f));
var n = f / (2 - f);
var n2 = n*n, n3 = n*n2, n4 = n*n3, n5 = n*n4, n6 = n*n5;
var A = a/(1+n) * (1 + 1/4*n2 + 1/64*n4 + 1/256*n6);
然后我自己转换了C#代码:
var a = 6378137;
var f = 1 / 298.257223563;
var e = Math.Sqrt(f * (2 - f));
var n = f / (2 - f);
var n2 = n * n;
var n3 = n2 * n;
var n4 = n3 * n;
var n5 = n4 * n;
var n6 = n5 * n;
var A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6);
它们应该相同,但是A的值不同。在Javascript
中,它是6367449.145823415
(我想要的),但是C#
给出6367444.6571225897487819833001
。我可以在项目中使用Javascript
代码,但是Unity去年方便地停止了对Javascript
的支持。
两个功能的输入相同。这里可能是什么问题?
答案 0 :(得分:13)
您在最后一个表达式中遇到了问题
var A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6);
在C#中,1 / 4 * n2
被评估为0
,因为默认情况下将1
和4
视为整数,并且整数除法1 / 4
给出0
。 1 / 64 * n4
和1 / 256 * n6
也会发生相同的情况。但是在JavaScript中只有64位浮点数,因此1 / 4
的求值为0.25
。
可能的解决方法:
var A = a / (1 + n) * (1 + 1 / 4.0 * n2 + 1 / 64.0 * n4 + 1 / 256.0 * n6);
现在的答案似乎完全一样。
注意:如@Lithium所述,您可能会发现在数字的末尾添加d
而不是.0
来表示为double
更为优雅。
答案 1 :(得分:-2)
在C#中,将所有变量用作类型double
。这些是默认情况下标准C#浮点数的两倍。
这应该给您相同的答案。
大多数语言都具有单精度浮点数和双精度浮点数(32位vs 64位)的概念。由于JavaScript是一种非严格类型的语言,因此我假设它正在接受这样一个事实,即您的数字应使用64位,而C#需要告知这一点。您还应尽可能避免在C#中使用var并使用实际类型,以避免出现类似:p
的情况。答案 2 :(得分:-2)
这可能与缺少对javascript中浮点数的处理有关。 C#可以很好地处理它,但不能使用Javascript。如果您想进一步了解Javascript数字中的一些怪癖,请查看下面的链接。