Skip to content

Commit 54c62a4

Browse files
committed
[R] 提取出Utils.BarAndTick和Utils.Tick函数。
1 parent 4930403 commit 54c62a4

2 files changed

Lines changed: 41 additions & 12 deletions

File tree

generator/mai/MA2Generator.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,10 @@ GENERATED_BY MuConvert v{8}
5858
/**
5959
* 把Rational的时间近似到RESOLUTION允许的最接近tick上
6060
*/
61-
private (int, int) BT(Rational r, int offset = 0)
62-
{
63-
if (offset != 0) r += new Rational(offset, RSL);
64-
return ((int)r.WholePart, (int)Math.Round((double)(r.FractionPart * RSL)));
65-
}
61+
private (int, int) BT(Rational r, int offset = 0) => Utils.BarAndTick(r, RSL, offset);
6662

6763
// 持续时间/等待时间,使用"总tick数"(可超过1小节),不是小节内tick
68-
protected int T(Rational r, int offset = 0)
69-
{
70-
var result = (int)Math.Round((double)(r* RSL));
71-
if (offset != 0) result = Math.Max(result + offset, result > 0 ? 1 : 0);
72-
return result;
73-
}
64+
protected int T(Rational r, int offset = 0) => Utils.Tick(r, RSL, offset, r > 0 ? 1 : 0);
7465
protected int T(int bar, int tick) => bar * RSL + tick;
7566
protected int T(MA2Line ma2Line) => T(ma2Line.Bar, ma2Line.Tick);
7667

utils/Utils.cs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Globalization;
1+
using System.Globalization;
22
using System.Numerics;
33
using System.Reflection;
44
using Rationals;
@@ -37,6 +37,33 @@ internal static Exception Fail(string msg = "")
3737
internal static int TokenType(string str) => _simaiLexerMap[str];
3838

3939
internal static bool IsModifier(int tokenType) => tokenType is L.MODIFIER or L.TAP_TO_STAR or L.STAR_TO_TAP or L.NO_STAR;
40+
41+
public static (int, int) BarAndTick(Rational time, int resolution, int extraTicks = 0)
42+
{
43+
var bar = time.WholePart;
44+
var tick = (time.FractionPart * resolution).Round();
45+
tick += extraTicks;
46+
47+
while (tick >= resolution)
48+
{
49+
tick -= resolution;
50+
bar++;
51+
}
52+
while (tick < 0)
53+
{
54+
tick += resolution;
55+
bar--;
56+
}
57+
58+
return ((int)bar, (int)tick);
59+
}
60+
61+
public static int Tick(Rational time, int resolution, int extraTicks = 0, int? min = null)
62+
{
63+
var r = (int)((time * resolution).Round() + extraTicks);
64+
if (min != null && r < min) r = min.Value;
65+
return r;
66+
}
4067
}
4168

4269
internal static class ExtensionUtils
@@ -63,6 +90,17 @@ public static Rational Ceil(this Rational r)
6390
return r.WholePart + (r.FractionPart == 0 ? 0 : 1);
6491
}
6592

93+
private static readonly Rational _half = new(1, 2);
94+
// 工作范围仅限非负数;舍入策略方面,使用与系统库Math.Round相同的“四舍六入五成双”算法。
95+
public static BigInteger Round(this Rational r)
96+
{
97+
if (r < 0) throw new ArgumentOutOfRangeException(nameof(r));
98+
var whole = r.WholePart;
99+
var frac = r.FractionPart;
100+
var shouldAdd = frac > _half || (frac == _half && whole % 2 == 1);
101+
return whole + (shouldAdd ? 1 : 0);
102+
}
103+
66104
public static Rational Sum(this IEnumerable<Rational> source)
67105
{
68106
return source.Aggregate(Rational.Zero, (acc, r) => acc + r);

0 commit comments

Comments
 (0)