-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMainWindow.xaml.cs
156 lines (141 loc) · 5.78 KB
/
MainWindow.xaml.cs
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Kerwis.DDouble;
using static IEEE754Inspector.MathTool;
namespace IEEE754Inspector;
public partial class MainWindow : Window
{
bool IsSingleMode => FloatModeTabControl.SelectedIndex == 0;
/// <summary> 如果十进制字符串表示可以Parse为当前浮点模式的对象则返回对应类型的box对象,否则返回原字符串 </summary>
object CurrentValue => IsSingleMode
? float.TryParse(RealValueBox.Text, out float valuef) ? valuef : RealValueBox.Text
: double.TryParse(RealValueBox.Text, out double valued) ? valued : RealValueBox.Text;
public MainWindow()
{
InitializeComponent();
FloatModeTabControl.SelectionChanged += FloatModeTabControl_SelectionChanged;
Title = $"IEE754检视器 v{typeof(MainWindow).Assembly.GetName().Version.ToString(3)} by 矢速";
ShowMsg("输入框内输入实数/位后按Enter.\n预计未来加入基本初等函数计算等功能");
}
private void FloatModeTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MantissaBitBox.MaxLength = IsSingleMode ? FP32MantBits : FP64MantBits;
ExponentBitBox.MaxLength = IsSingleMode ? FP32ExpoBits : FP64ExpoBits;
RefreshDisplayDec();
}
void BitBoxesKeyUp(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter) return;
if (IsSingleMode && TryParseBits(out int sign32, out int expo32, out int mantissa32))
RefreshDisplay32(SetupFPBinary<int, float>(sign32, expo32, mantissa32));
else if (TryParseBits(out long sign64, out long expo64, out long mantissa64))
RefreshDisplay64(SetupFPBinary<long, double>(sign64, expo64, mantissa64));
}
void RefreshDisplay64(double val)
{
(long sign, long expo, long mantissa) = SplitFPBinary<double, long>(val);
RealValueBox.Text = val.ToString("G17");
SignBitBox.Text = ToBinString(sign, 1);
ExponentBitBox.Text = ToBinString(expo, 11);
MantissaBitBox.Text = ToBinString(mantissa, 52);
//refresh details
bool isDenormal = expo == 0 && mantissa != 0;
double mantVal = SetupFPBinary<long, double>(0, 1023, mantissa);
if (expo == 0) {
expo++;
mantVal--;
}
MantissaValBox.Text = mantVal.ToString("G17");
ExponentValBox.Text = (expo - 1023).ToString();
SignValBox.Text = sign == 0 ? "+" : "-";
IsNormalLabel.Content = isDenormal ? "是" : "否";
long bits = AsInt64(val);
ShowMsg($"十六进制: {bits:X}\n二进制: {ToBinString(bits, 64)}");
try {
BitIncrementBox.Text = ((ddouble)Math.BitIncrement(val) - val).ToString();
BitDecrementBox.Text = ((ddouble)Math.BitDecrement(val) - val).ToString();
}
catch (Exception) { }
finally {
BitIncrementBox.Text = (Math.BitIncrement(val) - val).ToString();
BitDecrementBox.Text = (Math.BitDecrement(val) - val).ToString();
}
}
void RefreshDisplay32(float val)
{
(int sign, int expo, int mantissa) = SplitFPBinary<float, int>(val);
RealValueBox.Text = val.ToString("G8");
SignBitBox.Text = ToBinString(sign, 1);
ExponentBitBox.Text = ToBinString(expo, 8);
MantissaBitBox.Text = ToBinString(mantissa, 23);
//refresh details
bool isDenormal = expo == 0 && mantissa != 0;
float mantVal = SetupFPBinary<int, float>(0, 127, mantissa);
if (expo == 0) {
expo++;
mantVal--;
}
MantissaValBox.Text = mantVal.ToString("G8");
ExponentValBox.Text = (expo - 127).ToString();
SignValBox.Text = sign == 0 ? "+" : "-";
IsNormalLabel.Content = isDenormal ? "是" : "否";
int bits = AsInt32(val);
ShowMsg($"十六进制: {bits:X}\n二进制: {ToBinString(bits, 32)}");
try {
BitIncrementBox.Text = ((ddouble)MathF.BitIncrement(val) - val).ToString();
BitDecrementBox.Text = ((ddouble)MathF.BitDecrement(val) - val).ToString();
}
catch (Exception) { }
finally {
BitIncrementBox.Text = ((double)MathF.BitIncrement(val) - val).ToString();
BitDecrementBox.Text = ((double)MathF.BitDecrement(val) - val).ToString();
}
}
void RefreshDisplayDec(Func<float, float> floatChangeFunc = null, Func<double, double> doubleChangeFunc = null)
{
switch (CurrentValue) {
case float f:
RefreshDisplay32(floatChangeFunc != null ? floatChangeFunc(f) : f); break;
case double d:
RefreshDisplay64(doubleChangeFunc != null ? doubleChangeFunc(d) : d); break;
case string originalStr:
ShowMsg($"“{originalStr}”不能解析为当前所选类型浮点数!"); break;
default:
ShowMsg($"异常, 意外的类型: {CurrentValue.GetType().Name}, 值: {CurrentValue}."); break;
}
}
private void IncrementButton_Click(object sender, RoutedEventArgs e) => RefreshDisplayDec(MathF.BitIncrement, Math.BitIncrement);
private void DecrementButton_Click(object sender, RoutedEventArgs e) => RefreshDisplayDec(MathF.BitDecrement, Math.BitDecrement);
private void RealValueBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter) return;
RefreshDisplayDec();
}
/// <summary>
/// 将符号位、指数位、尾数位的字符串表示的二进制解析填充为目标值类型。不足的位数补0
/// </summary>
/// <typeparam name="Tbin">输出的值类型</typeparam>
bool TryParseBits<Tbin>(out Tbin sign, out Tbin expo, out Tbin mantissa) where Tbin : unmanaged
{
expo = mantissa = default;
char c;
if ((c = TryParseBin(SignBitBox.Text, out sign)) != '\0') {
ShowMsg($"符号位输入\"{SignBitBox.Text}\"为非法字符'{c}'.\n应该输入0或1.");
}
else if ((c = TryParseBin(ExponentBitBox.Text, out expo)) != '\0') {
ShowMsg($"指数输入\"{ExponentBitBox.Text}\"含非法字符'{c}'.\n应该输入0或1.");
}
else if ((c = TryParseBin(MantissaBitBox.Text, out mantissa)) != '\0') {
ShowMsg($"尾数输入\"{MantissaBitBox.Text}\"含非法字符'{c}'.\n应该输入0或1.");
}
else return true;
return false;
}
private void ShowMsg(object msg)
{
DebugTool.LogMsg(msg, 2);
MsgBox.Text = msg.ToString();
}
}