diff --git a/src/BizHawk.Client.Common/tools/Watch/ByteWatch.cs b/src/BizHawk.Client.Common/tools/Watch/ByteWatch.cs index cede5907cc..6035f0341a 100644 --- a/src/BizHawk.Client.Common/tools/Watch/ByteWatch.cs +++ b/src/BizHawk.Client.Common/tools/Watch/ByteWatch.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Globalization; - -using BizHawk.Common.StringExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -76,54 +74,14 @@ namespace BizHawk.Client.Common { try { - byte val = 0; - switch (Type) + byte val = Type switch { - case WatchDisplayType.Unsigned: - if (value.IsUnsigned()) - { - val = (byte)int.Parse(value); - } - else - { - return false; - } - - break; - case WatchDisplayType.Signed: - if (value.IsSigned()) - { - val = (byte)(sbyte)int.Parse(value); - } - else - { - return false; - } - - break; - case WatchDisplayType.Hex: - if (value.IsHex()) - { - val = (byte)int.Parse(value, NumberStyles.HexNumber); - } - else - { - return false; - } - - break; - case WatchDisplayType.Binary: - if (value.IsBinary()) - { - val = (byte)Convert.ToInt32(value, 2); - } - else - { - return false; - } - - break; - } + WatchDisplayType.Unsigned => byte.Parse(value), + WatchDisplayType.Signed => (byte)sbyte.Parse(value), + WatchDisplayType.Hex => byte.Parse(value, NumberStyles.HexNumber), + WatchDisplayType.Binary => Convert.ToByte(value, 2), + _ => 0 + }; PokeByte(val); return true; diff --git a/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs b/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs index cd979fc403..6c9645ba5e 100644 --- a/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs +++ b/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Globalization; - -using BizHawk.Common.StringExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -79,77 +77,16 @@ namespace BizHawk.Client.Common { try { - uint val = 0; - switch (Type) + uint val = Type switch { - case WatchDisplayType.Unsigned: - if (value.IsUnsigned()) - { - val = (uint)int.Parse(value); - } - else - { - return false; - } - - break; - case WatchDisplayType.Signed: - if (value.IsSigned()) - { - val = (uint)int.Parse(value); - } - else - { - return false; - } - - break; - case WatchDisplayType.Hex: - if (value.IsHex()) - { - val = (uint)int.Parse(value, NumberStyles.HexNumber); - } - else - { - return false; - } - - break; - case WatchDisplayType.FixedPoint_20_12: - if (value.IsFixedPoint()) - { - val = (uint)(int)(double.Parse(value) * 4096.0); - } - else - { - return false; - } - - break; - case WatchDisplayType.FixedPoint_16_16: - if (value.IsFixedPoint()) - { - val = (uint)(int)(double.Parse(value) * 65536.0); - } - else - { - return false; - } - - break; - case WatchDisplayType.Float: - if (value.IsFloat()) - { - var bytes = BitConverter.GetBytes(float.Parse(value)); - val = BitConverter.ToUInt32(bytes, 0); - } - else - { - return false; - } - - break; - } + WatchDisplayType.Unsigned => uint.Parse(value), + WatchDisplayType.Signed => (uint)int.Parse(value), + 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), + _ => 0 + }; PokeDWord(val); return true; @@ -198,7 +135,7 @@ namespace BizHawk.Client.Common { var bytes = BitConverter.GetBytes(val); var _float = BitConverter.ToSingle(bytes, 0); - return _float.ToString(); + return _float.ToString(NumberFormatInfo.InvariantInfo); } string FormatBinary() @@ -217,8 +154,8 @@ namespace BizHawk.Client.Common WatchDisplayType.Unsigned => val.ToString(), WatchDisplayType.Signed => ((int)val).ToString(), WatchDisplayType.Hex => $"{val:X8}", - WatchDisplayType.FixedPoint_20_12 => $"{(int)val / 4096.0:0.######}", - WatchDisplayType.FixedPoint_16_16 => $"{(int)val / 65536.0:0.######}", + WatchDisplayType.FixedPoint_20_12 => ((int)val / 4096.0).ToString("0.######", NumberFormatInfo.InvariantInfo), + WatchDisplayType.FixedPoint_16_16 => ((int)val / 65536.0).ToString("0.######", NumberFormatInfo.InvariantInfo), WatchDisplayType.Float => FormatFloat(), WatchDisplayType.Binary => FormatBinary(), _ => val.ToString() diff --git a/src/BizHawk.Client.Common/tools/Watch/WordWatch.cs b/src/BizHawk.Client.Common/tools/Watch/WordWatch.cs index 7032e18f44..58d1d25322 100644 --- a/src/BizHawk.Client.Common/tools/Watch/WordWatch.cs +++ b/src/BizHawk.Client.Common/tools/Watch/WordWatch.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Globalization; - -using BizHawk.Common.StringExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -74,65 +72,15 @@ namespace BizHawk.Client.Common { try { - ushort val = 0; - switch (Type) + ushort val = Type switch { - case WatchDisplayType.Unsigned: - if (value.IsUnsigned()) - { - val = (ushort)int.Parse(value); - } - else - { - return false; - } - - break; - case WatchDisplayType.Signed: - if (value.IsSigned()) - { - val = (ushort)(short)int.Parse(value); - } - else - { - return false; - } - - break; - case WatchDisplayType.Hex: - if (value.IsHex()) - { - val = (ushort)int.Parse(value, NumberStyles.HexNumber); - } - else - { - return false; - } - - break; - case WatchDisplayType.Binary: - if (value.IsBinary()) - { - val = (ushort)Convert.ToInt32(value, 2); - } - else - { - return false; - } - - break; - case WatchDisplayType.FixedPoint_12_4: - if (value.IsFixedPoint()) - { - val = (ushort)(double.Parse(value) * 16.0); - } - else - { - return false; - } - - break; - } + WatchDisplayType.Unsigned => ushort.Parse(value), + WatchDisplayType.Signed => (ushort)short.Parse(value), + WatchDisplayType.Hex => ushort.Parse(value, NumberStyles.HexNumber), + WatchDisplayType.Binary => Convert.ToUInt16(value, 2), + WatchDisplayType.FixedPoint_12_4 => (ushort)(double.Parse(value, NumberFormatInfo.InvariantInfo) * 16.0), + _ => 0 + }; PokeWord(val); return true; @@ -183,7 +131,7 @@ namespace BizHawk.Client.Common _ when !IsValid => "-", WatchDisplayType.Unsigned => val.ToString(), WatchDisplayType.Signed => ((short) val).ToString(), WatchDisplayType.Hex => $"{val:X4}", - WatchDisplayType.FixedPoint_12_4 => $"{val / 16.0:F4}", + WatchDisplayType.FixedPoint_12_4 => ((short)val / 16.0).ToString("F4", NumberFormatInfo.InvariantInfo), WatchDisplayType.Binary => Convert .ToString(val, 2) .PadLeft(16, '0') diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs index 10418aba82..2e09d34efe 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs @@ -2,10 +2,8 @@ using System.Globalization; using System.Linq; using System.Windows.Forms; - -using BizHawk.Common.StringExtensions; -using BizHawk.Common.NumberExtensions; using BizHawk.Client.Common; +using BizHawk.Common.NumberExtensions; namespace BizHawk.Client.EmuHawk { @@ -27,7 +25,7 @@ namespace BizHawk.Client.EmuHawk set { var changed = _size != value; - + _size = value; if (changed) { @@ -87,17 +85,20 @@ namespace BizHawk.Client.EmuHawk _ => sbyte.MinValue }; - private double Max12_4 => MaxUnsignedInt / 16.0; + private const double Max12_4 = short.MaxValue / 16.0; + private const double Min12_4 = short.MinValue / 16.0; - private double Max20_12 => MaxUnsignedInt / 4096.0; + private const double Max20_12 = int.MaxValue / 4096.0; + private const double Min20_12 = int.MinValue / 4096.0; - private double Max16_16 => MaxUnsignedInt / 65536.0; + private const double Max16_16 = int.MaxValue / 65536.0; + private const double Min16_16 = int.MinValue / 65536.0; - private static double _12_4_Unit => 1 / 16.0; + private const double _12_4_Unit = 1 / 16.0; - private static double _20_12_Unit => 1 / 4096.0; + private const double _20_12_Unit = 1 / 4096.0; - private static double _16_16_Unit => 1 / 65536.0; + private const double _16_16_Unit = 1 / 65536.0; public override void ResetText() { @@ -173,88 +174,14 @@ namespace BizHawk.Client.EmuHawk }; break; case WatchDisplayType.FixedPoint_12_4: - MaxLength = 9; + MaxLength = 10; break; case WatchDisplayType.Float: - MaxLength = 21; + MaxLength = 40; break; case WatchDisplayType.FixedPoint_20_12: case WatchDisplayType.FixedPoint_16_16: - MaxLength = 64; - break; - } - } - - protected override void OnKeyPress(KeyPressEventArgs e) - { - if (e.KeyChar == '\b' || e.KeyChar == 22 || e.KeyChar == 1 || e.KeyChar == 3) - { - return; - } - - if (e.KeyChar == '.') - { - if (Text.Contains(".") && !SelectedText.Contains(".")) - { - e.Handled = true; - return; - } - } - else if (e.KeyChar == '-') - { - if (Text.Contains("-") && !SelectedText.Contains("-")) - { - e.Handled = true; - return; - } - } - - switch (_type) - { - default: - case WatchDisplayType.Binary: - if (!e.KeyChar.IsBinary()) - { - e.Handled = true; - } - - break; - case WatchDisplayType.FixedPoint_12_4: - case WatchDisplayType.FixedPoint_20_12: - case WatchDisplayType.FixedPoint_16_16: - if (!e.KeyChar.IsFixedPoint()) - { - e.Handled = true; - } - - break; - case WatchDisplayType.Float: - if (!e.KeyChar.IsFloat()) - { - e.Handled = true; - } - - break; - case WatchDisplayType.Hex: - if (!e.KeyChar.IsHex()) - { - e.Handled = true; - } - - break; - case WatchDisplayType.Signed: - if (!e.KeyChar.IsSigned()) - { - e.Handled = true; - } - - break; - case WatchDisplayType.Unsigned: - if (!e.KeyChar.IsUnsigned()) - { - e.Handled = true; - } - + MaxLength = 24; break; } } @@ -321,47 +248,47 @@ namespace BizHawk.Client.EmuHawk Text = hexVal.ToHexString(MaxLength); break; case WatchDisplayType.FixedPoint_12_4: - var f12val = double.Parse(text); + var f12val = double.Parse(text, NumberFormatInfo.InvariantInfo); if (f12val > Max12_4 - _12_4_Unit) { - f12val = 0; + f12val = Min12_4; } else { f12val += _12_4_Unit; } - Text = f12val.ToString(); + Text = f12val.ToString(NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.FixedPoint_20_12: - var f24val = double.Parse(text); - if (f24val >= Max20_12 - _20_12_Unit) + var f20val = double.Parse(text, NumberFormatInfo.InvariantInfo); + if (f20val > Max20_12 - _20_12_Unit) { - f24val = 0; + f20val = Min20_12; } else { - f24val += _20_12_Unit; + f20val += _20_12_Unit; } - Text = f24val.ToString(); + Text = f20val.ToString(NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.FixedPoint_16_16: - var f16val = double.Parse(text); - if (f16val >= Max16_16 - _16_16_Unit) + var f16val = double.Parse(text, NumberFormatInfo.InvariantInfo); + if (f16val > Max16_16 - _16_16_Unit) { - f16val = 0; + f16val = Min16_16; } else { f16val += _16_16_Unit; } - Text = f16val.ToString(); + Text = f16val.ToString(NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.Float: - var dVal = double.Parse(text); - if (dVal > double.MaxValue - 1) + var dVal = double.Parse(text, NumberFormatInfo.InvariantInfo); + if (dVal > float.MaxValue - 1) { dVal = 0; } @@ -370,7 +297,7 @@ namespace BizHawk.Client.EmuHawk dVal++; } - Text = dVal.ToString(); + Text = dVal.ToString(NumberFormatInfo.InvariantInfo); break; } } @@ -437,8 +364,8 @@ namespace BizHawk.Client.EmuHawk Text = hexVal.ToHexString(MaxLength); break; case WatchDisplayType.FixedPoint_12_4: - var f12val = double.Parse(text); - if (f12val < 0 + _12_4_Unit) + var f12val = double.Parse(text, NumberFormatInfo.InvariantInfo); + if (f12val < Min12_4 + _12_4_Unit) { f12val = Max12_4; } @@ -447,24 +374,24 @@ namespace BizHawk.Client.EmuHawk f12val -= _12_4_Unit; } - Text = f12val.ToString(); + Text = f12val.ToString(NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.FixedPoint_20_12: - var f24val = double.Parse(text); - if (f24val < 0 + _20_12_Unit) + var f20val = double.Parse(text, NumberFormatInfo.InvariantInfo); + if (f20val < Min20_12 + _20_12_Unit) { - f24val = Max20_12; + f20val = Max20_12; } else { - f24val -= _20_12_Unit; + f20val -= _20_12_Unit; } - Text = f24val.ToString(); + Text = f20val.ToString(NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.FixedPoint_16_16: - var f16val = double.Parse(text); - if (f16val < 0 + _16_16_Unit) + var f16val = double.Parse(text, NumberFormatInfo.InvariantInfo); + if (f16val < Min16_16 + _16_16_Unit) { f16val = Max16_16; } @@ -473,11 +400,11 @@ namespace BizHawk.Client.EmuHawk f16val -= _16_16_Unit; } - Text = f16val.ToString(); + Text = f16val.ToString(NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.Float: - var dval = double.Parse(text); - if (dval > double.MaxValue - 1) + var dval = double.Parse(text, NumberFormatInfo.InvariantInfo); + if (dval < float.MinValue + 1) { dval = 0; } @@ -486,7 +413,7 @@ namespace BizHawk.Client.EmuHawk dval--; } - Text = dval.ToString(); + Text = dval.ToString(NumberFormatInfo.InvariantInfo); break; } } @@ -505,113 +432,32 @@ namespace BizHawk.Client.EmuHawk return; } - switch (_type) - { - case WatchDisplayType.Signed: - Text = Text.OnlySigned(); - break; - case WatchDisplayType.Unsigned: - Text = Text.OnlyUnsigned(); - break; - case WatchDisplayType.Binary: - Text = Text.OnlyBinary(); - break; - case WatchDisplayType.Hex: - Text = Text.OnlyHex(); - break; - case WatchDisplayType.FixedPoint_12_4: - case WatchDisplayType.FixedPoint_20_12: - case WatchDisplayType.FixedPoint_16_16: - Text = Text.OnlyFixedPoint(); - break; - case WatchDisplayType.Float: - Text = Text.OnlyFloat(); - break; - } - base.OnTextChanged(e); } public int? ToRawInt() { - if (string.IsNullOrWhiteSpace(Text)) + try { - if (Nullable) + return _type switch { - return null; - } - - return 0; + WatchDisplayType.Signed => int.Parse(Text), + WatchDisplayType.Unsigned => (int)uint.Parse(Text), + WatchDisplayType.Binary => Convert.ToInt32(Text, 2), + WatchDisplayType.Hex => int.Parse(Text, NumberStyles.HexNumber), + 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), + _ => int.Parse(Text) + }; } - - switch (_type) + catch { - case WatchDisplayType.Signed: - if (Text.IsSigned()) - { - return Text == "-" ? 0 : int.Parse(Text); - } - - break; - case WatchDisplayType.Unsigned: - if (Text.IsUnsigned()) - { - return (int)uint.Parse(Text); - } - - break; - case WatchDisplayType.Binary: - if (Text.IsBinary()) - { - return Convert.ToInt32(Text, 2); - } - - break; - case WatchDisplayType.Hex: - if (Text.IsHex()) - { - return int.Parse(Text, NumberStyles.HexNumber); - } - - break; - case WatchDisplayType.FixedPoint_12_4: - if (Text.IsFixedPoint()) - { - return (int)(double.Parse(Text) * 16.0); - } - - break; - case WatchDisplayType.FixedPoint_20_12: - if (Text.IsFixedPoint()) - { - return (int)(double.Parse(Text) * 4096.0); - } - - break; - case WatchDisplayType.FixedPoint_16_16: - if (Text.IsFixedPoint()) - { - return (int)(double.Parse(Text) * 65536.0); - } - - break; - case WatchDisplayType.Float: - if (Text.IsFloat()) - { - if (Text == "-" || Text == ".") - { - return 0; - } - - float val = float.Parse(Text); - var bytes = BitConverter.GetBytes(val); - return BitConverter.ToInt32(bytes, 0); - } - - break; + // ignored } - return 0; + return Nullable ? null : 0; } public void SetFromRawInt(int? val) @@ -637,18 +483,18 @@ namespace BizHawk.Client.EmuHawk Text = val.Value.ToHexString(MaxLength); break; case WatchDisplayType.FixedPoint_12_4: - Text = $"{val.Value / 16.0:F5}"; + Text = (val.Value / 16.0).ToString("F5", NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.FixedPoint_20_12: - Text = $"{val.Value / 4096.0:F5}"; + Text = (val.Value / 4096.0).ToString("F5", NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.FixedPoint_16_16: - Text = $"{val.Value / 65536.0:F5}"; + 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); - Text = $"{_float:F6}"; + Text = _float.ToString("F6", NumberFormatInfo.InvariantInfo); break; } } diff --git a/src/BizHawk.Common/Extensions/NumericStringExtensions.cs b/src/BizHawk.Common/Extensions/NumericStringExtensions.cs index 2d156f05f5..7db7040c3c 100644 --- a/src/BizHawk.Common/Extensions/NumericStringExtensions.cs +++ b/src/BizHawk.Common/Extensions/NumericStringExtensions.cs @@ -1,5 +1,4 @@ using System.Linq; -using System.Text; namespace BizHawk.Common.StringExtensions { @@ -13,26 +12,6 @@ namespace BizHawk.Common.StringExtensions /// should exclude the prefix 0b public static bool IsBinary(this string? str) => !string.IsNullOrWhiteSpace(str) && str.All(IsBinary); - /// iff is '.' or a digit - /// Also this has nothing to do with fixed- vs. floating-point numbers, a better name would be IsUnsignedDecimal. - public static bool IsFixedPoint(this char c) => IsUnsigned(c) || c == '.'; - - /// - /// iff is not ,
- /// all chars of are '.' or a digit, and
- /// contains at most 1 decimal separator '.' - ///
- /// - /// should exclude the suffix M.
- /// This method returning for some does not imply that float.TryParse will also return .
- /// Also this has nothing to do with fixed- vs. floating-point numbers, a better name would be IsUnsignedDecimal. - ///
- public static bool IsFixedPoint(this string? str) => !string.IsNullOrWhiteSpace(str) && str.Count(c => c == '.') <= 1 && str.All(IsFixedPoint); - - /// iff is '-', '.', or a digit - /// Also this has nothing to do with fixed- vs. floating-point numbers, a better name would be IsSignedDecimal. - public static bool IsFloat(this char c) => c.IsFixedPoint() || c == '-'; - /// iff is a hex digit ([0-9A-Fa-f]) public static bool IsHex(this char c) => IsUnsigned(c) || 'A' <= char.ToUpperInvariant(c) && char.ToUpperInvariant(c) <= 'F'; @@ -46,128 +25,13 @@ namespace BizHawk.Common.StringExtensions /// iff is a digit public static bool IsUnsigned(this char c) => char.IsDigit(c); - /// iff is not and all chars of are digits - public static bool IsUnsigned(this string? str) => !string.IsNullOrWhiteSpace(str) && str.All(IsUnsigned); - - /// - /// A copy of with characters removed so that the whole thing passes IsBinary.
- /// That is, all chars of the copy will be either '0' or '1'. - ///
- public static string OnlyBinary(this string? raw) => string.IsNullOrWhiteSpace(raw) ? string.Empty : string.Concat(raw.Where(IsBinary)); - /// /// A copy of with characters removed so that the whole thing passes IsHex.
/// That is, all chars of the copy will be hex digits ([0-9A-F]). ///
public static string OnlyHex(this string? raw) => string.IsNullOrWhiteSpace(raw) ? string.Empty : string.Concat(raw.Where(IsHex)).ToUpperInvariant(); - /// - /// A copy of with characters removed so that the whole thing passes IsUnsigned.
- /// That is, all chars of the copy will be digits. - ///
- public static string OnlyUnsigned(this string? raw) => string.IsNullOrWhiteSpace(raw) ? string.Empty : string.Concat(raw.Where(IsUnsigned)); - -#pragma warning disable CS8602 - - /// - /// iff is not ,
- /// the first char of is '-', '.', or a digit,
- /// all subsequent chars of are '.' or a digit, and
- /// contains at most 1 decimal separator '.' - ///
- /// - /// should exclude the suffix f.
- /// This method returning for some does not imply that float.TryParse will also return .
- /// Also this has nothing to do with fixed- vs. floating-point numbers, a better name would be IsSignedDecimal. - ///
- public static bool IsFloat(this string? str) => !string.IsNullOrWhiteSpace(str) && str.Count(c => c == '.') <= 1 && str[0].IsFloat() && str.Substring(1).All(IsFixedPoint); - - /// - /// iff is not , - /// the first char of is '-' or a digit, and - /// all subsequent chars of are digits - /// - public static bool IsSigned(this string? str) => !string.IsNullOrWhiteSpace(str) && str[0].IsSigned() && str.Substring(1).All(IsUnsigned); - - /// - /// A copy of with characters removed so that the whole thing passes IsFixedPoint.
- /// That is, the all chars of the copy will be '.' or a digit and the copy will contain at most 1 decimal separator '.'. - ///
- /// - /// The returned value may not be parseable by float.TryParse.
- /// Also this has nothing to do with fixed- vs. floating-point numbers, a better name would be IsUnsignedDecimal. - ///
- public static string OnlyFixedPoint(this string? raw) - { - if (string.IsNullOrWhiteSpace(raw)) return string.Empty; - var output = new StringBuilder(); - var usedDot = false; - foreach (var chr in raw) - { - if (chr == '.') - { - if (usedDot) continue; - output.Append(chr); - usedDot = true; - } - else if (chr.IsUnsigned()) output.Append(chr); - } - return output.ToString(); - } - - /// - /// A copy of with characters removed so that the whole thing passes IsFloat.
- /// That is, the first char of the copy will be '-', '.', or a digit,
- /// all subsequent chars of the copy will be '.' or a digit, and
- /// the copy will contain at most 1 decimal separator '.'. - ///
- /// - /// If contains a serialized negative decimal, it must be at the start ([0] == '-') or the sign will be dropped.
- /// The returned value may not be parseable by float.TryParse.
- /// Also this has nothing to do with fixed- vs. floating-point numbers, a better name would be IsSignedDecimal. - ///
- public static string OnlyFloat(this string? raw) - { - if (string.IsNullOrWhiteSpace(raw)) return string.Empty; - - var output = new StringBuilder(); - var usedDot = false; - - var first = raw[0]; - if (first.IsFloat()) - { - output.Append(first); - if (first == '.') usedDot = true; - } - - for (int i = 1, l = raw.Length; i < l; i++) - { - var chr = raw[i]; - if (chr == '.') - { - if (usedDot) continue; - output.Append(chr); - usedDot = true; - } - else if (chr.IsUnsigned()) output.Append(chr); - } - - return output.ToString(); - } - - /// - /// A copy of with characters removed so that the whole thing passes IsSigned.
- /// That is, the first char of the copy will be '-' or a digit, and all subsequent chars of the copy will be digits. - ///
- /// If contains a serialized negative integer, it must be at the start ([0] == '-') or the sign will be dropped. - public static string OnlySigned(this string? raw) - { - if (string.IsNullOrWhiteSpace(raw)) return string.Empty; - return raw[0].IsSigned() - ? raw[0] + string.Concat(raw.Skip(1).Where(IsUnsigned)) - : string.Concat(raw.Skip(1).Where(IsUnsigned)); - } - -#pragma warning restore CS8602 + /// iff is not and all chars of are digits + public static bool IsUnsigned(this string? str) => !string.IsNullOrWhiteSpace(str) && str.All(IsUnsigned); } }