Skip to content

Commit

Permalink
hack for fp-determinism across Unity and .NET 8
Browse files Browse the repository at this point in the history
  • Loading branch information
akopetsch committed Jun 21, 2024
1 parent 2fb08ff commit 0b0b37c
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 5 deletions.
22 changes: 22 additions & 0 deletions ByteSerialization.Tests/Unit/IO/EndianBinaryReaderTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT

using ByteSerialization.IO;
using Xunit;

namespace ByteSerialization.Tests.Unit.IO
{
public class EndianBinaryReaderTest
{
[Fact]
public void Test_ReadSingle_BE() =>
AssertReadResult(13.5407705f, "4158 a6ff", Endianness.BigEndian, r => r.ReadSingle());

private void AssertReadResult<T>(T expectedValue, string hexStringToRead, Endianness endianness, Func<EndianBinaryReader, T> readFunc)
{
using var ms = new MemoryStream(HexStringConverter.ToByteArray(hexStringToRead));
using var reader = new EndianBinaryReader(ms, endianness);
T actualValue = readFunc.Invoke(reader);
Assert.Equal(expectedValue, actualValue);
}
}
}
24 changes: 24 additions & 0 deletions ByteSerialization.Tests/Unit/IO/EndianBinaryWriterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT

using ByteSerialization.IO;
using Xunit;

namespace ByteSerialization.Tests.Unit.IO
{
public class EndianBinaryWriterTest
{
[Fact]
public void Test_WriteSingle_BE() =>
AssertWriteResult("4158 a6ff", 13.5407705f, Endianness.BigEndian, (r, x) => r.Write(x));

private void AssertWriteResult<T>(string expectedHexString, T valueToWrite, Endianness endianness, Action<EndianBinaryWriter, T> writeFunc)
{
using var ms = new MemoryStream();
using var writer = new EndianBinaryWriter(ms, endianness);
writeFunc.Invoke(writer, valueToWrite);
byte[] actualBytes = ms.ToArray();
byte[] expectedBytes = HexStringConverter.ToByteArray(expectedHexString);
Assert.True(Enumerable.SequenceEqual(expectedBytes, actualBytes));
}
}
}
2 changes: 1 addition & 1 deletion ByteSerialization/ByteSerialization.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Nullable>disable</Nullable>
<Authors>Alexander Kopetsch</Authors>
<Version>0.0.1.0</Version>
<PackageVersion>0.0.1-alpha.8</PackageVersion>
<PackageVersion>0.0.1-alpha.9</PackageVersion>
<PackageProjectUrl>https://github.com/akopetsch/ByteSerialization</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
6 changes: 4 additions & 2 deletions ByteSerialization/IO/EndianBinaryReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,12 @@ public ulong ReadUInt64() =>
BytesSwapper.SwapIf(_reader.ReadUInt64(), IsBigEndian);

public float ReadSingle() =>
BytesSwapper.SwapIf(_reader.ReadSingle(), IsBigEndian);
BitConverter.Int32BitsToSingle(BytesSwapper.SwapIf(_reader.ReadInt32(), IsBigEndian));
// HACK: regular ``BytesSwapper.SwapIf(_reader.ReadSingle(), IsBigEndian);`` is not deterministic across .NET 8 and Unity 2022.3.30f1 (LTS)

public double ReadDouble() =>
BytesSwapper.SwapIf(_reader.ReadDouble(), IsBigEndian);
BitConverter.Int64BitsToDouble(BytesSwapper.SwapIf(_reader.ReadInt64(), IsBigEndian));
// HACK: regular ``BytesSwapper.SwapIf(_reader.ReadDouble(), IsBigEndian);`` is probably also not deterministic across .NET 8 and Unity 2022.3.30f1 (LTS)

#endregion

Expand Down
6 changes: 4 additions & 2 deletions ByteSerialization/IO/EndianBinaryWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,12 @@ public void Write(ulong value) =>
_writer.Write(BytesSwapper.SwapIf(value, IsBigEndian));

public void Write(float value) =>
_writer.Write(BytesSwapper.SwapIf(value, IsBigEndian));
_writer.Write(BytesSwapper.SwapIf(BitConverter.SingleToInt32Bits(value), IsBigEndian));
// HACK: regular ``_writer.Write(BytesSwapper.SwapIf(value, IsBigEndian));`` is probably not deterministic across .NET 8 and Unity 2022.3.30f1 (LTS)

public void Write(double value) =>
_writer.Write(BytesSwapper.SwapIf(value, IsBigEndian));
_writer.Write(BytesSwapper.SwapIf(BitConverter.DoubleToInt64Bits(value), IsBigEndian));
// HACK: regular ``_writer.Write(BytesSwapper.SwapIf(value, IsBigEndian));`` is probably not deterministic across .NET 8 and Unity 2022.3.30f1 (LTS)

#endregion

Expand Down

0 comments on commit 0b0b37c

Please sign in to comment.