Skip to content

Commit 16f8a77

Browse files
committed
fix: saturation overflow
1 parent e3fe2a8 commit 16f8a77

1 file changed

Lines changed: 7 additions & 5 deletions

File tree

src/FixedMathSharp/Numerics/Scalars/Fixed64.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ private static void Multiply64To128(ulong a, ulong b, out ulong hi, out ulong lo
482482
/// <param name="lo">Lower 64 bits of the 128-bit value.</param>
483483
/// <param name="shift">Number of bits to shift right. Must be in the range 1..63.</param>
484484
/// <param name="overflowed">
485-
/// True if rounding caused the 64-bit shifted result to overflow.
485+
/// True if the shifted or rounded result exceeded 64 bits.
486486
/// </param>
487487
/// <returns>
488488
/// The rounded 64-bit result of ((hi:lo) >> shift).
@@ -492,6 +492,10 @@ private static ulong ShiftRightRoundedToEven(ulong hi, ulong lo, int shift, out
492492
{
493493
// Preconditions: 1 <= shift <= 63
494494

495+
// Bits above the low 64 result bits must be preserved as saturation state
496+
// before the lower projection can wrap back into range.
497+
overflowed = (hi >> shift) != 0UL;
498+
495499
// Integer part after shifting right by 'shift':
496500
// result = ((hi << (64 - shift)) | (lo >> shift))
497501
ulong result = (hi << (64 - shift)) | (lo >> shift);
@@ -510,12 +514,10 @@ private static ulong ShiftRightRoundedToEven(ulong hi, ulong lo, int shift, out
510514
remainder > half ||
511515
(remainder == half && (result & 1UL) != 0);
512516

513-
overflowed = false;
514-
515517
if (shouldRoundUp)
516518
{
517519
ulong incremented = result + 1UL;
518-
overflowed = incremented < result;
520+
overflowed |= incremented < result;
519521
result = incremented;
520522
}
521523

@@ -914,4 +916,4 @@ public int CompareTo(Fixed64 other)
914916
}
915917

916918
#endregion
917-
}
919+
}

0 commit comments

Comments
 (0)