-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProgram.cs
More file actions
121 lines (104 loc) · 4.22 KB
/
Program.cs
File metadata and controls
121 lines (104 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Made for Geometry Dash 2.2
using System.Globalization;
internal class Program
{
private static void Main(string[] args)
{
double MAX_DECIMAL_VALUE = (double)Decimal.MaxValue;
double MIN_DECIMAL_VALUE = MinDecimalValue();
float freezeDistance;
float velocity;
double ulpValue;
// main program
Console.WriteLine("Input the distance you want to freeze at:");
string? input;
while (true)
{
input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("Empty input. Please enter a value.");
continue;
}
if (float.TryParse(input.Trim(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out freezeDistance))
{
if (float.IsNaN(freezeDistance) || float.IsInfinity(freezeDistance))
{
Console.WriteLine("Invalid input. Please try again.");
continue;
}
break; // valid value entered; continue program
}
Console.WriteLine("Invalid input. Please try again.");
}
ulpValue = Ulp(freezeDistance);
Console.WriteLine("Input the velocity you want to use:");
while (true)
{
input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("Empty input. Please enter a value.");
continue;
}
if (float.TryParse(input.Trim(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out velocity))
{
break; // valid value entered; continue program
}
Console.WriteLine("Invalid input. Please enter a valid floating-point number.");
}
TPS(ulpValue, velocity);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
// functions
void TPS(double ulpValue, float velocity)
{
double distanceToFreeze = FloorPow2(freezeDistance);
double min = (2 + double.Epsilon) / ulpValue * velocity;
double max = 4 / ulpValue * velocity;
Console.WriteLine(
$"Minimum tps to freeze at {
(CanRepresentAsDecimal(distanceToFreeze) ? (decimal)distanceToFreeze : distanceToFreeze)
} units (floored to the nearest power of 2)"
+ $" with velocity {velocity} units/s: "
+ (CanRepresentAsDecimal(min) ? (decimal)min : min)
);
Console.WriteLine(
$"Maximum tps to freeze at {
(CanRepresentAsDecimal(distanceToFreeze) ? (decimal)distanceToFreeze : distanceToFreeze)
} with velocity {velocity} units/s: "
+ (CanRepresentAsDecimal(max) ? (decimal)max : max)
);
}
bool CanRepresentAsDecimal(double value)
{
return value >= MIN_DECIMAL_VALUE && value <= MAX_DECIMAL_VALUE;
}
double FloorPow2(float x)
{
if (x <= 0.0) return 0.0;
int exp = (int)Math.Floor(Math.Log2(x));
return Math.Pow(2, exp);
}
double MinDecimalValue()
{
//smallest positive decimal value
double d = (double)new decimal(1, 0, 0, false, 28);
//get the next greater double value to ensure it's representable as decimal after casting
double nextGreater = BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(d) + 1);
return nextGreater;
}
double Ulp(float distance)
{
if (distance <= 0)
{
freezeDistance = 0;
return float.Epsilon;
}
int bits = BitConverter.SingleToInt32Bits(distance);
int nextBits = bits + 1;
float nextValue = BitConverter.Int32BitsToSingle(nextBits);
return nextValue - distance;
}
}
}