Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #320 : Fix precision in serialization of double and float #322

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Jil/Serialize/Methods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ static void _ProxyFloat(TextWriter writer, float f)
return;
}

writer.Write(f.ToString(invariant));
writer.Write(f.ToString("R",invariant));
}

static readonly MethodInfo ProxyDouble = typeof(Methods).GetMethod("_ProxyDouble", BindingFlags.Static | BindingFlags.NonPublic);
Expand All @@ -1279,7 +1279,7 @@ static void _ProxyDouble(TextWriter writer, double d)
return;
}

writer.Write(d.ToString(invariant));
writer.Write(d.ToString("R",invariant));
}

static readonly MethodInfo ProxyDecimal = typeof(Methods).GetMethod("_ProxyDecimal", BindingFlags.Static | BindingFlags.NonPublic);
Expand Down
160 changes: 80 additions & 80 deletions Jil/Serialize/ThunkWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Jil.Serialize
{
using System.Threading.Tasks;
namespace Jil.Serialize
{
delegate void StringThunkDelegate<T>(ref ThunkWriter writer, T data, int depth);

#region Strings and Enums and oh god why
Expand Down Expand Up @@ -94,9 +94,9 @@ enum ConstantString_000Escape : byte
EscapeSequence_000B = 8,
EscapeSequence_000E = 9,
EscapeSequence_000F = 10
}

enum ConstantString_001Escape : byte
}
enum ConstantString_001Escape : byte
{
EscapeSequence_0010 = 0,
EscapeSequence_0011 = 1,
Expand Down Expand Up @@ -125,8 +125,8 @@ enum ConstantString_DaysOfWeek : byte
Thursday = 12,
Friday = 15,
Saturday = 18
}

}
static class ThunkWriterCharArrays
{
public static readonly char[] Escape000Prefix = new char[] { '\\', 'u', '0', '0', '0' };
Expand All @@ -144,7 +144,7 @@ static class ThunkWriterCharArrays

#endregion

partial struct ThunkWriter
partial struct ThunkWriter
{
StringBuilder Builder;

Expand Down Expand Up @@ -276,42 +276,42 @@ public static bool IsConstantDaysOfWeek(string str, out ConstantString_DaysOfWee
case "Sat": c = ConstantString_DaysOfWeek.Saturday; return true;
default: c = 0; return false;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Init()
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Init()
{
Builder = (Builder ?? new StringBuilder()).Clear();
Builder = (Builder ?? new StringBuilder()).Clear();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(float f)
{
Write(f.ToString(CultureInfo.InvariantCulture));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(float f)
{
Write(f.ToString("R",CultureInfo.InvariantCulture));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(double d)
{
Write(d.ToString(CultureInfo.InvariantCulture));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(double d)
{
Write(d.ToString("R",CultureInfo.InvariantCulture));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(decimal m)
{
Write(m.ToString(CultureInfo.InvariantCulture));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(decimal m)
{
Write(m.ToString(CultureInfo.InvariantCulture));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(char[] ch, int startIx, int len)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(char[] ch, int startIx, int len)
{
Builder.Append(ch, startIx, len);
Builder.Append(ch, startIx, len);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(char ch)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(char ch)
{
Builder.Append(ch);
Builder.Append(ch);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down Expand Up @@ -379,54 +379,54 @@ public void WriteDayOfWeek(ConstantString_DaysOfWeek str)
Builder.Append(ThunkWriterCharArrays.ConstantString_DaysOfWeek, ix, 3);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Write(string strRef)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Write(string strRef)
{
Builder.Append(strRef);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string StaticToString()
{
Builder.Append(strRef);
return Builder.ToString();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string StaticToString()
#region Slow Builds Only
// these methods are only called to compare faster methods to serializing
// as such they need not be optimized

public void Write(byte b)
{
Write(b.ToString());
}
public void Write(sbyte b)
{
return Builder.ToString();
}

#region Slow Builds Only
// these methods are only called to compare faster methods to serializing
// as such they need not be optimized

public void Write(byte b)
{
Write(b.ToString());
}
public void Write(sbyte b)
{
Write(b.ToString());
}
public void Write(short b)
{
Write(b.ToString());
}
public void Write(ushort b)
{
Write(b.ToString());
}
public void Write(int b)
{
Write(b.ToString());
}
public void Write(uint b)
{
Write(b.ToString());
}
public void Write(long b)
{
Write(b.ToString());
}
public void Write(ulong b)
{
Write(b.ToString());
}
#endregion
}
}
Write(b.ToString());
}
public void Write(short b)
{
Write(b.ToString());
}
public void Write(ushort b)
{
Write(b.ToString());
}
public void Write(int b)
{
Write(b.ToString());
}
public void Write(uint b)
{
Write(b.ToString());
}
public void Write(long b)
{
Write(b.ToString());
}
public void Write(ulong b)
{
Write(b.ToString());
}
#endregion
}
}
10 changes: 5 additions & 5 deletions JilTests/DynamicSerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ public void SecondsTimeSpans()
stringJson = JSON.SerializeDynamic(ts, Options.SecondsSinceUnixEpoch);
}

var dotNetStr = ts.TotalSeconds.ToString(CultureInfo.InvariantCulture);
var dotNetStr = ts.TotalSeconds.ToString("R",CultureInfo.InvariantCulture);

if (dotNetStr.IndexOf('.') != -1) dotNetStr = dotNetStr.TrimEnd('0');
if (streamJson.IndexOf('.') != -1) streamJson = streamJson.TrimEnd('0');
Expand Down Expand Up @@ -1019,7 +1019,7 @@ public void MillsecondsTimeSpans()
stringJson = JSON.SerializeDynamic(ts, Options.MillisecondsSinceUnixEpoch);
}

var dotNetStr = ts.TotalMilliseconds.ToString();
var dotNetStr = ts.TotalMilliseconds.ToString("R", CultureInfo.InvariantCulture);

if (dotNetStr.IndexOf('.') != -1) dotNetStr = dotNetStr.TrimEnd('0');
if (streamJson.IndexOf('.') != -1) streamJson = streamJson.TrimEnd('0');
Expand Down Expand Up @@ -1394,7 +1394,7 @@ public void Issue158()
const string json = "4.3563456344358765e+10";

double res = JSON.DeserializeDynamic(json);
var shouldMatch = double.Parse(json);
var shouldMatch = double.Parse(json,NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
var diff = Math.Abs(res - shouldMatch);

Assert.Equal(shouldMatch, res);
Expand All @@ -1404,7 +1404,7 @@ public void Issue158()
const string json = "4.356345634435876535634563443587653563456344358765356345634435876535634563443587653563456344358765e+10";

double res = JSON.DeserializeDynamic(json);
var shouldMatch = double.Parse(json);
var shouldMatch = double.Parse(json, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
var diff = Math.Abs(res - shouldMatch);

Assert.Equal(shouldMatch, res);
Expand All @@ -1414,7 +1414,7 @@ public void Issue158()
const string json = "4.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444445e+10";

double res = JSON.DeserializeDynamic(json);
var shouldMatch = double.Parse(json);
var shouldMatch = double.Parse(json, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
var diff = Math.Abs(res - shouldMatch);

Assert.Equal(shouldMatch, res);
Expand Down
Loading