[英]Weird number conversion / encoding in Unity C#
I have this iOS project that embed an unity scene as a view.我有一个嵌入统一场景作为视图的 iOS 项目。 This problem occur on a device that set a localize that number has comma
,
as decimal seperator, rather than a point .
此问题发生设置一个局部化该号码具有逗号的设备上
,
为十进制分隔符,而不是一个点.
I sent a parameter string from native code (swift) to unity.我从本机代码(swift)发送了一个参数字符串到 unity。 Unity then parse the string from iOS, make a new parameters to embed in another http request.
Unity 然后解析来自 iOS 的字符串,创建一个新参数以嵌入另一个 http 请求。
this is the log in xcode:这是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}
I expected that I send 98.42519685039369, 100.06561679790026
, but for some reason, it becomes 9842519685039368.0, 10006561679790026.0
in the data request json string.我希望我发送
98.42519685039369, 100.06561679790026
,但由于某种原因,它在数据请求中变成了9842519685039368.0, 10006561679790026.0
字符串。
How to fix this?如何解决这个问题? I have another log from a different device, with localize en-US and it seems the problem doesn't occur here.
我有另一个来自不同设备的日志,使用 localize en-US,似乎这里没有出现问题。
The code in Unity (search for is_the_problem_here
to jump right to the quetionable line: 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.
}
The other log:另一个日志:
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}
** UPDATE ** ** 更新 **
I've tried following this link but it's still not working as expect (same output as the first)我试过按照这个链接,但它仍然没有按预期工作(与第一个输出相同)
var converter = new FormattedDecimalConverter(CultureInfo.GetCultureInfo("en-US"));
string data = JsonConvert.SerializeObject(updateRequest, converter);
The 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();
}
}
Sorry for being clueless.抱歉我一无所知。 What am I doing wrong here?
我在这里做错了什么?
** UPDATE ** ** 更新 **
so changing Convert.toDouble()
to double.Parse(ceiling, CultureInfo.InvariantCulture)
fix the problem.因此将
Convert.toDouble()
更改为double.Parse(ceiling, CultureInfo.InvariantCulture)
解决问题。 What weird issue.什么奇怪的问题。
Per default Convert.ToDouble(string)
uses the language/region settings of the device the code is running on.默认
Convert.ToDouble(string)
使用运行代码的设备的语言/区域设置。
In some cultures the .
在某些文化中,
.
character is not considered as the decimal splitter but rather the decimal group character.字符不被视为十进制分隔符,而是十进制组字符。
=> eg 1.000
is not one but rather one thousand! => 例如
1.000
不是一而是一千!
If dealing with string
s across multiple devices you should always make sure to use the cultured overload Convert.ToDouble(string, IFormatProvider)
and pass in the CultureInfo.InvariantCulture
which is based on en-us
.如果处理跨多个设备的
string
,您应该始终确保使用文化重载Convert.ToDouble(string, IFormatProvider)
并传入基于en-us
的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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.