diff --git a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs index 260e94bc92..8c6093933e 100644 --- a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using BizHawk.Common; +using BizHawk.Common.NumberExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -287,7 +288,7 @@ namespace BizHawk.Client.Common LogCallback($"Warning: Attempted read {addr} outside memory size of {d.Size}"); return default; } - return BitConverter.ToSingle(BitConverter.GetBytes(d.PeekUint(addr, _isBigEndian)), 0); + return NumberExtensions.ReinterpretAsF32(d.PeekUint(addr, _isBigEndian)); } public void WriteFloat(long addr, float value, string domain = null) @@ -303,7 +304,7 @@ namespace BizHawk.Client.Common LogCallback($"Warning: Attempted write {addr} outside memory size of {d.Size}"); return; } - d.PokeUint(addr, BitConverter.ToUInt32(BitConverter.GetBytes(value), 0), _isBigEndian); + d.PokeUint(addr, NumberExtensions.ReinterpretAsUInt32(value), _isBigEndian); } public int ReadS8(long addr, string domain = null) => (sbyte) ReadUnsigned(addr, 1, domain); diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs index adf05e6485..5cfbdde961 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs @@ -1,23 +1,17 @@ using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; using BizHawk.Common; using BizHawk.Common.CollectionExtensions; using BizHawk.Common.NumberExtensions; using BizHawk.Emulation.Common; +using static BizHawk.Common.NumberExtensions.NumberExtensions; // ReSharper disable PossibleInvalidCastExceptionInForeachLoop namespace BizHawk.Client.Common.RamSearchEngine { public class RamSearchEngine { - /// TODO move to BizHawk.Common - private static float ReinterpretAsF32(long l) - { - return Unsafe.As(ref l); - } - private Compare _compareTo = Compare.Previous; private IMiniWatch[] _watchList = Array.Empty(); diff --git a/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs b/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs index dfffdb3cac..3e3f623bd7 100644 --- a/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs +++ b/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Globalization; +using BizHawk.Common.NumberExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -79,7 +80,7 @@ namespace BizHawk.Client.Common WatchDisplayType.Hex => uint.Parse(value, NumberStyles.HexNumber), WatchDisplayType.FixedPoint_20_12 => (uint)(double.Parse(value, NumberFormatInfo.InvariantInfo) * 4096.0), WatchDisplayType.FixedPoint_16_16 => (uint)(double.Parse(value, NumberFormatInfo.InvariantInfo) * 65536.0), - WatchDisplayType.Float => BitConverter.ToUInt32(BitConverter.GetBytes(float.Parse(value, NumberFormatInfo.InvariantInfo)), 0), + WatchDisplayType.Float => NumberExtensions.ReinterpretAsUInt32(float.Parse(value, NumberFormatInfo.InvariantInfo)), _ => 0 }; @@ -128,8 +129,7 @@ namespace BizHawk.Client.Common { string FormatFloat() { - var bytes = BitConverter.GetBytes(val); - var _float = BitConverter.ToSingle(bytes, 0); + var _float = NumberExtensions.ReinterpretAsF32(val); return _float.ToString(NumberFormatInfo.InvariantInfo); } diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs index 7cddd85f2b..c4859c1498 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs @@ -457,7 +457,7 @@ namespace BizHawk.Client.EmuHawk WatchDisplayType.FixedPoint_12_4 => (int)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 16.0), WatchDisplayType.FixedPoint_20_12 => (int)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 4096.0), WatchDisplayType.FixedPoint_16_16 => (int)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 65536.0), - WatchDisplayType.Float => BitConverter.ToInt32(BitConverter.GetBytes(float.Parse(Text, NumberFormatInfo.InvariantInfo)), 0), + WatchDisplayType.Float => (int)NumberExtensions.ReinterpretAsUInt32(float.Parse(Text, NumberFormatInfo.InvariantInfo)), _ => int.Parse(Text) }; } @@ -501,8 +501,7 @@ namespace BizHawk.Client.EmuHawk Text = (val.Value / 65536.0).ToString("F5", NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.Float: - var bytes = BitConverter.GetBytes(val.Value); - float _float = BitConverter.ToSingle(bytes, 0); + float _float = NumberExtensions.ReinterpretAsF32((uint)val.Value); Text = _float.ToString("F6", NumberFormatInfo.InvariantInfo); break; } diff --git a/src/BizHawk.Common/Extensions/NumberExtensions.cs b/src/BizHawk.Common/Extensions/NumberExtensions.cs index 2afcd6353c..0f236461f2 100644 --- a/src/BizHawk.Common/Extensions/NumberExtensions.cs +++ b/src/BizHawk.Common/Extensions/NumberExtensions.cs @@ -155,5 +155,11 @@ namespace BizHawk.Common.NumberExtensions /// don't use this in cores without picking a suitable ε public static bool HawkFloatEquality(this float f, float other, float ε = ReallySmallNumber) => Math.Abs(other - f) < ε; + + /// Reinterprets the byte representation of as a float + public static float ReinterpretAsF32(uint value) => Unsafe.As(ref value); + + /// Reinterprets the byte representation of as a uint + public static uint ReinterpretAsUInt32(float value) => Unsafe.As(ref value); } }