demo2
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user