| | | 1 | | //======================================================================= |
| | | 2 | | // Signed192.cs |
| | | 3 | | //======================================================================= |
| | | 4 | | // MIT License, Copyright (c) 2024–present David Oravsky (mrdav30) |
| | | 5 | | // See LICENSE file in the project root for full license information. |
| | | 6 | | //======================================================================= |
| | | 7 | | |
| | | 8 | | using System.Runtime.CompilerServices; |
| | | 9 | | |
| | | 10 | | namespace FixedMathSharp; |
| | | 11 | | |
| | | 12 | | /// <summary> |
| | | 13 | | /// A signed two's-complement value wide enough for sums of full-domain |
| | | 14 | | /// Q32.32 endpoint-difference products. |
| | | 15 | | /// </summary> |
| | | 16 | | internal readonly struct Signed192 |
| | | 17 | | { |
| | 160489 | 18 | | public static Signed192 One => Signed(Fixed64.One.m_rawValue); |
| | | 19 | | |
| | | 20 | | internal readonly ulong High; |
| | | 21 | | internal readonly ulong Middle; |
| | | 22 | | internal readonly ulong Low; |
| | | 23 | | |
| | | 24 | | internal Signed192(ulong high, ulong middle, ulong low) |
| | | 25 | | { |
| | 9669232 | 26 | | High = high; |
| | 9669232 | 27 | | Middle = middle; |
| | 9669232 | 28 | | Low = low; |
| | 9669232 | 29 | | } |
| | | 30 | | |
| | 20757302 | 31 | | internal bool IsZero => (High | Middle | Low) == 0UL; |
| | | 32 | | |
| | 20703041 | 33 | | internal int Sign => IsZero ? 0 : (High & (1UL << 63)) != 0UL ? -1 : 1; |
| | | 34 | | |
| | 1917417 | 35 | | internal static Signed192 Raw(Fixed64 value) => Signed(value.m_rawValue); |
| | | 36 | | |
| | | 37 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 38 | | internal static Signed192 Signed(long value) |
| | | 39 | | { |
| | 2621574 | 40 | | ulong extension = value < 0L ? ulong.MaxValue : 0UL; |
| | 2621574 | 41 | | return new Signed192(extension, extension, unchecked((ulong)value)); |
| | | 42 | | } |
| | | 43 | | |
| | | 44 | | /// <summary> |
| | | 45 | | /// Narrows a five-word signed value to a three-word signed value, discarding the two most significant words. |
| | | 46 | | /// </summary> |
| | 307178 | 47 | | internal static Signed192 NarrowValue(Signed320 value) => new(value.Word2, value.Word1, value.Word0); |
| | | 48 | | |
| | | 49 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 50 | | internal static bool TryNarrowSigned(Signed320 value, out Signed192 result) |
| | | 51 | | { |
| | 3064922 | 52 | | ulong extension = (value.Word2 & (1UL << 63)) != 0UL ? ulong.MaxValue : 0UL; |
| | 3064922 | 53 | | if (value.Word4 != extension || value.Word3 != extension) |
| | | 54 | | { |
| | 495769 | 55 | | result = default; |
| | 495769 | 56 | | return false; |
| | | 57 | | } |
| | | 58 | | |
| | 2569153 | 59 | | result = new Signed192(value.Word2, value.Word1, value.Word0); |
| | 2569153 | 60 | | return true; |
| | | 61 | | } |
| | | 62 | | |
| | | 63 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 64 | | internal static Signed192 NarrowProven(Signed320 value) |
| | | 65 | | { |
| | 25287 | 66 | | _ = TryNarrowSigned(value, out Signed192 result); |
| | 25287 | 67 | | return result; |
| | | 68 | | } |
| | | 69 | | |
| | | 70 | | /// <summary> |
| | | 71 | | /// Narrow a Signed576 value to a Signed192 value, discarding the upper 384 bits. |
| | | 72 | | /// </summary> |
| | 27 | 73 | | internal static Signed192 NarrowValue(Signed576 value) => new(value.Word2, value.Word1, value.Word0); |
| | | 74 | | |
| | | 75 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 76 | | internal static bool TryNarrowSigned(Signed576 value, out Signed192 result) |
| | | 77 | | { |
| | 1171344 | 78 | | ulong extension = (value.Word2 & (1UL << 63)) != 0UL ? ulong.MaxValue : 0UL; |
| | 1171344 | 79 | | if (value.Word8 != extension || value.Word7 != extension || value.Word6 != extension |
| | 1171344 | 80 | | || value.Word5 != extension || value.Word4 != extension || value.Word3 != extension) |
| | | 81 | | { |
| | 407718 | 82 | | result = default; |
| | 407718 | 83 | | return false; |
| | | 84 | | } |
| | | 85 | | |
| | 763626 | 86 | | result = new Signed192(value.Word2, value.Word1, value.Word0); |
| | 763626 | 87 | | return true; |
| | | 88 | | } |
| | | 89 | | |
| | | 90 | | internal bool Equals(Signed192 other) => |
| | 6 | 91 | | ((High ^ other.High) |
| | 6 | 92 | | | (Middle ^ other.Middle) |
| | 6 | 93 | | | (Low ^ other.Low)) == 0UL; |
| | | 94 | | } |