Не делай этого!decimal
не для year.month
.Технически вы можете решить проблему и различить 3.1m
и 3.10m
(decimal.GetBits
выручает);Вот код для академического использования * только 1009 *:
private static decimal EerieArithmetics(decimal d1, decimal d2) {
int y1 = (int)d1;
int m1 = (int)((d1 % 1m) * ((((decimal.GetBits(d1)[3] >> 16) & 31) == 2) ? 100m : 10m));
int y2 = (int)d2;
int m2 = (int)((d2 % 1m) * ((((decimal.GetBits(d2)[3] >> 16) & 31) == 2) ? 100m : 10m));
int y = y1 + y2 + (m1 + m2) / 12;
int m = (m1 + m2) % 12;
return y + (m == 10 ? 0.10m : m > 10 ? m / 100.00m : m / 10.0m);
}
Демонстрация:
Tuple<decimal, decimal>[] tests = new Tuple<decimal, decimal>[] {
Tuple.Create(3.10m, 2.8m),
Tuple.Create( 3.1m, 2.8m),
Tuple.Create( 3.0m, 2.8m),
Tuple.Create( 3.0m, 2.0m),
Tuple.Create( 3m, 2m),
Tuple.Create( 3.8m, 2.4m),
Tuple.Create(3.10m, 3.10m),
Tuple.Create( 2.8m, 2.2m),
Tuple.Create(2.11m, 2.2m),
};
string report = string.Join(Environment.NewLine, tests
.Select(test =>
$"{test.Item1,5} + {test.Item2,5} == {EerieArithmetics(test.Item1, test.Item2),5}"));
Console.Write(report);
Результат:
3.10 + 2.8 == 6.6
3.1 + 2.8 == 5.9
3.0 + 2.8 == 5.8
3.0 + 2.0 == 5
3 + 2 == 5
3.8 + 2.4 == 6
3.10 + 3.10 == 7.8
2.8 + 2.2 == 4.10
2.11 + 2.2 == 5.1
Надеюсь, я напугал вас таким использованием decimal
.В качестве быстрого и грязного патча (если вы не можете использовать какую-либо библиотеку, кроме стандартной), вы можете попробовать DateTime
class:
DateTime d1 = new DateTime(3, 10, 1); // 1 Oct 3 AD
DateTime d2 = new DateTime(2, 8, 1); // 1 Aug 2 AD
DateTime result = d1
.AddYears(d2.Year)
.AddMonths(d2.Month); // 1 Jun 6 AD
// 6.6
Console.Write($"{result.Year}.{result.Month}");