#nullable disable using System; using System.Linq; namespace BizHawk.Common.NumberExtensions { public static class NumberExtensions { public static string ToHexString(this int n, int numDigits) { return string.Format($"{{0:X{numDigits}}}", n); } public static string ToHexString(this uint n, int numDigits) { return string.Format($"{{0:X{numDigits}}}", n); } public static string ToHexString(this long n, int numDigits) { return string.Format($"{{0:X{numDigits}}}", n); } public static string ToHexString(this ulong n, int numDigits) { return string.Format($"{{0:X{numDigits}}}", n); } public static bool Bit(this byte b, int index) { return (b & (1 << index)) != 0; } public static bool Bit(this int b, int index) { return (b & (1 << index)) != 0; } public static bool Bit(this ushort b, int index) { return (b & (1 << index)) != 0; } public static bool In(this int i, params int[] options) { return options.Any(j => i == j); } public static byte BinToBCD(this byte v) { return (byte)(((v / 10) * 16) + (v % 10)); } public static byte BCDtoBin(this byte v) { return (byte)(((v / 16) * 10) + (v % 16)); } /// /// Receives a number and returns the number of hexadecimal digits it is /// Note: currently only returns 2, 4, 6, or 8 /// public static int NumHexDigits(this long i) { // now this is a bit of a trick. if it was less than 0, it must have been >= 0x80000000 and so takes all 8 digits if (i < 0) { return 8; } if (i < 0x100) { return 2; } if (i < 0x10000) { return 4; } if (i < 0x1000000) { return 6; } if (i < 0x100000000) { return 8; } return 16; } /// /// The % operator is a remainder operator. (e.g. -1 mod 4 returns -1, not 3.) /// public static int Mod(this int a, int b) { return a - (b * (int)Math.Floor((float)a / b)); } /// /// Force the value to be strictly between min and max (both excluded) /// /// Anything that implements /// Value that will be clamped /// Minimum allowed /// Maximum allowed /// The value if strictly between min and max; otherwise min (or max depending of what is passed) public static T Clamp(this T val, T min, T max) where T : IComparable { if (val.CompareTo(min) < 0) { return min; } if (val.CompareTo(max) > 0) { return max; } return val; } public static int RoundToInt(this float f) => (int) Math.Round(f); /// 2^-53 private const double ExtremelySmallNumber = 1.1102230246251565E-16; /// public static bool HawkFloatEquality(this double d, double other, double ε = ExtremelySmallNumber) => Math.Abs(other - d) < ε; /// 2^-24 private const float ReallySmallNumber = 5.96046448E-08f; /// 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) < ε; } }