Files
Workspace/Assets/Demos/Demo2/Domain/SaturatingMath.cs
T
2026-08-18 02:03:34 +08:00

51 lines
1.8 KiB
C#

#nullable enable
using System;
namespace Demo2.Domain
{
public static class SaturatingMath
{
public const long Scale = 1000;
public static long Add(long left, long right)
{
if (right > 0 && left > long.MaxValue - right) return long.MaxValue;
if (right < 0 && left < long.MinValue - right) return long.MinValue;
return left + right;
}
public static long Multiply(long left, long right)
{
if (left == 0 || right == 0) return 0;
if (left == long.MinValue && right == -1) return long.MaxValue;
if (right == long.MinValue && left == -1) return long.MaxValue;
var negative = (left < 0) ^ (right < 0);
var a = AbsUnsigned(left);
var b = AbsUnsigned(right);
if (a > (ulong)long.MaxValue / b) return negative ? long.MinValue : long.MaxValue;
var value = (long)(a * b);
return negative ? -value : value;
}
public static long MultiplyScaled(long value, long multiplierMilli)
{
if (value == 0 || multiplierMilli == 0) return 0;
var product = Multiply(value, multiplierMilli);
if (product == long.MaxValue || product == long.MinValue) return product;
return product / Scale;
}
public static string Format(long value)
{
var abs = value == long.MinValue ? long.MaxValue : Math.Abs(value);
if (abs < 1_000_000_000) return value.ToString("N0");
var exponent = (int)Math.Floor(Math.Log10(abs));
var mantissa = value / Math.Pow(10, exponent);
return mantissa.ToString("0.##") + "e" + exponent;
}
private static ulong AbsUnsigned(long value) => value < 0 ? (ulong)(-(value + 1)) + 1UL : (ulong)value;
}
}