Unity C# 中的奇怪数字转换/编码
Weird number conversion / encoding in Unity C#
我有这个 iOS 项目,它嵌入了一个统一场景作为视图。
此问题发生在设置本地化的设备上,该数字具有逗号 ,
作为小数点分隔符,而不是点 .
我从本机代码 (swift) 向 unity 发送了一个参数字符串。然后 Unity 解析来自 iOS 的字符串,创建一个新参数嵌入到另一个 http 请求中。
这是登录 xcode:
param from iOS: 615d48538edef900126a784e***616957b6f59835001137ae7b***98.42519685039369***100.06561679790026
Request Object:
- distanceFromCeiling: 9,84251968503937E+15
- distanceFromSideWall: 1,000656167979E+16
- Obj: : UpdateRequest
- Obj.distanceFromCeiling: : 9,84251968503937E+15
- Obj.distanceFromSideWall: : 1,000656167979E+16
DATA request {"distanceFromCeiling":9842519685039368.0,"distanceFromSideWall":10006561679790026.0}
我预计我会发送 98.42519685039369, 100.06561679790026
,但由于某种原因,它在数据请求 json 字符串中变成了 9842519685039368.0, 10006561679790026.0
。
如何解决这个问题?我有另一个来自不同设备的日志,使用 localize en-US,似乎这里没有出现问题。
Unity 中的代码(搜索 is_the_problem_here
直接跳转到有问题的行:
using System;
using System.Collections;
using System.Collections.Generic;
using Lean.Touch;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.UI;
using BestHTTP;
using System.Text;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using UnityEngine.UIElements;
public class GameManager : MonoBehaviour
{
// Other functions
// ====================================
void callApiFromIOS(string param)
{
Debug.Log("param from iOS: " + param);
string[] str = param.Split(new string[] { "***" }, StringSplitOptions.None);
// is_the_problem_here
System.Nullable <double> distanceFromCeiling = null;
System.Nullable<double> distanceFromSideWall = null;
if (str != null && str.Length >= 4)
{
string ceiling = str[2];
if (!ceiling.Equals("null"))
{
// is_the_problem_here
distanceFromCeiling = Convert.ToDouble(ceiling);
}
string sideWall = str[3];
if (!sideWall.Equals("null"))
{
// is_the_problem_here
distanceFromSideWall = Convert.ToDouble(sideWall);
}
}
Debug.Log("Request Object: ");
Debug.Log("- distanceFromCeiling: " + distanceFromCeiling);
Debug.Log("- distanceFromSideWall: " + distanceFromSideWall);
UpdateRequest updateRequest = new UpdateRequest(distanceFromCeiling, distanceFromSideWall);
Debug.Log(" - Obj: : " + updateRequest);
Debug.Log(" - Obj.distanceFromCeiling: : " + updateRequest.distanceFromCeiling);
Debug.Log(" - Obj.distanceFromSideWall: : " + updateRequest.distanceFromSideWall);
// is_the_problem_here
string data = JsonConvert.SerializeObject(updateRequest);
Debug.Log("DATA request " + data);
// the rest of the code is set the json data as request body and send http.
}
其他日志:
param from iOS: 615d48538edef900126a784e***616957b6f59835001137ae7b***98.42519685039369***100.06561679790026
Request Object:
- distanceFromCeiling: 98.4251968503937
- distanceFromSideWall: 100.0656167979
- Obj: : UpdateRequest
- Obj.distanceFromCeiling: : 98.4251968503937
- Obj.distanceFromSideWall: : 100.0656167979
DATA request {"distanceFromCeiling":98.425196850393689,"distanceFromSideWall":100.06561679790026}
** 更新 **
我试过按照这个 link 但它仍然没有按预期工作(与第一个输出相同)
var converter = new FormattedDecimalConverter(CultureInfo.GetCultureInfo("en-US"));
string data = JsonConvert.SerializeObject(updateRequest, converter);
转换器class:
using System;
using System.Globalization;
using Newtonsoft.Json;
internal class FormattedDecimalConverter : JsonConverter
{
private CultureInfo culture;
public FormattedDecimalConverter(CultureInfo culture)
{
this.culture = culture;
}
public override bool CanConvert(Type objectType)
{
return true;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(Convert.ToString(value, culture));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
抱歉无能为力。我在这里做错了什么?
** 更新 **
所以将 Convert.toDouble()
更改为 double.Parse(ceiling, CultureInfo.InvariantCulture)
解决了这个问题。什么奇怪的问题。
默认情况下 Convert.ToDouble(string)
使用设备的 language/region 设置代码 运行 打开。
在某些文化中,.
字符不被视为十进制分隔符,而是十进制组字符。
=> 例如1.000
不是一而是一千!
如果在多个设备上处理 string
,您应该始终确保使用基于 en-us
.
的文化化重载 Convert.ToDouble(string, IFormatProvider)
and pass in the CultureInfo.InvariantCulture
string ceiling = str[2];
if (!ceiling.Equals("null"))
{
// is_the_problem_here
distanceFromCeiling = Convert.ToDouble(ceiling, CultureInfo.InvariantCulture);
}
string sideWall = str[3];
if (!sideWall.Equals("null"))
{
// is_the_problem_here
distanceFromSideWall = Convert.ToDouble(sideWall, CultureInfo.InvariantCulture);
}
我有这个 iOS 项目,它嵌入了一个统一场景作为视图。
此问题发生在设置本地化的设备上,该数字具有逗号 ,
作为小数点分隔符,而不是点 .
我从本机代码 (swift) 向 unity 发送了一个参数字符串。然后 Unity 解析来自 iOS 的字符串,创建一个新参数嵌入到另一个 http 请求中。
这是登录 xcode:
param from iOS: 615d48538edef900126a784e***616957b6f59835001137ae7b***98.42519685039369***100.06561679790026
Request Object:
- distanceFromCeiling: 9,84251968503937E+15
- distanceFromSideWall: 1,000656167979E+16
- Obj: : UpdateRequest
- Obj.distanceFromCeiling: : 9,84251968503937E+15
- Obj.distanceFromSideWall: : 1,000656167979E+16
DATA request {"distanceFromCeiling":9842519685039368.0,"distanceFromSideWall":10006561679790026.0}
我预计我会发送 98.42519685039369, 100.06561679790026
,但由于某种原因,它在数据请求 json 字符串中变成了 9842519685039368.0, 10006561679790026.0
。
如何解决这个问题?我有另一个来自不同设备的日志,使用 localize en-US,似乎这里没有出现问题。
Unity 中的代码(搜索 is_the_problem_here
直接跳转到有问题的行:
using System;
using System.Collections;
using System.Collections.Generic;
using Lean.Touch;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.UI;
using BestHTTP;
using System.Text;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using UnityEngine.UIElements;
public class GameManager : MonoBehaviour
{
// Other functions
// ====================================
void callApiFromIOS(string param)
{
Debug.Log("param from iOS: " + param);
string[] str = param.Split(new string[] { "***" }, StringSplitOptions.None);
// is_the_problem_here
System.Nullable <double> distanceFromCeiling = null;
System.Nullable<double> distanceFromSideWall = null;
if (str != null && str.Length >= 4)
{
string ceiling = str[2];
if (!ceiling.Equals("null"))
{
// is_the_problem_here
distanceFromCeiling = Convert.ToDouble(ceiling);
}
string sideWall = str[3];
if (!sideWall.Equals("null"))
{
// is_the_problem_here
distanceFromSideWall = Convert.ToDouble(sideWall);
}
}
Debug.Log("Request Object: ");
Debug.Log("- distanceFromCeiling: " + distanceFromCeiling);
Debug.Log("- distanceFromSideWall: " + distanceFromSideWall);
UpdateRequest updateRequest = new UpdateRequest(distanceFromCeiling, distanceFromSideWall);
Debug.Log(" - Obj: : " + updateRequest);
Debug.Log(" - Obj.distanceFromCeiling: : " + updateRequest.distanceFromCeiling);
Debug.Log(" - Obj.distanceFromSideWall: : " + updateRequest.distanceFromSideWall);
// is_the_problem_here
string data = JsonConvert.SerializeObject(updateRequest);
Debug.Log("DATA request " + data);
// the rest of the code is set the json data as request body and send http.
}
其他日志:
param from iOS: 615d48538edef900126a784e***616957b6f59835001137ae7b***98.42519685039369***100.06561679790026
Request Object:
- distanceFromCeiling: 98.4251968503937
- distanceFromSideWall: 100.0656167979
- Obj: : UpdateRequest
- Obj.distanceFromCeiling: : 98.4251968503937
- Obj.distanceFromSideWall: : 100.0656167979
DATA request {"distanceFromCeiling":98.425196850393689,"distanceFromSideWall":100.06561679790026}
** 更新 **
我试过按照这个 link 但它仍然没有按预期工作(与第一个输出相同)
var converter = new FormattedDecimalConverter(CultureInfo.GetCultureInfo("en-US"));
string data = JsonConvert.SerializeObject(updateRequest, converter);
转换器class:
using System;
using System.Globalization;
using Newtonsoft.Json;
internal class FormattedDecimalConverter : JsonConverter
{
private CultureInfo culture;
public FormattedDecimalConverter(CultureInfo culture)
{
this.culture = culture;
}
public override bool CanConvert(Type objectType)
{
return true;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(Convert.ToString(value, culture));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
抱歉无能为力。我在这里做错了什么?
** 更新 **
所以将 Convert.toDouble()
更改为 double.Parse(ceiling, CultureInfo.InvariantCulture)
解决了这个问题。什么奇怪的问题。
默认情况下 Convert.ToDouble(string)
使用设备的 language/region 设置代码 运行 打开。
在某些文化中,.
字符不被视为十进制分隔符,而是十进制组字符。
=> 例如1.000
不是一而是一千!
如果在多个设备上处理 string
,您应该始终确保使用基于 en-us
.
Convert.ToDouble(string, IFormatProvider)
and pass in the CultureInfo.InvariantCulture
string ceiling = str[2];
if (!ceiling.Equals("null"))
{
// is_the_problem_here
distanceFromCeiling = Convert.ToDouble(ceiling, CultureInfo.InvariantCulture);
}
string sideWall = str[3];
if (!sideWall.Equals("null"))
{
// is_the_problem_here
distanceFromSideWall = Convert.ToDouble(sideWall, CultureInfo.InvariantCulture);
}