Skip to content

Commit 8e6434b

Browse files
committed
完成程序员计算器
1 parent 6ff6007 commit 8e6434b

File tree

8 files changed

+863
-106
lines changed

8 files changed

+863
-106
lines changed

app/src/main/java/com/equationl/calculator_compose/dataModel/KeyBoardData.kt

Lines changed: 146 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,64 @@ package com.equationl.calculator_compose.dataModel
22

33
import androidx.compose.ui.graphics.Color
44

5-
const val KeyIndex_Percentage = 19
6-
const val KeyIndex_CE = 1001
7-
const val KeyIndex_C = 1002
8-
const val KeyIndex_Back = 1003
9-
const val KeyIndex_Reciprocal = 16
10-
const val KeyIndex_Pow2 = 17
11-
const val KeyIndex_Sqrt = 18
12-
const val KeyIndex_Divide = 13
13-
const val KeyIndex_7 = 7
14-
const val KeyIndex_8 = 8
15-
const val KeyIndex_9 = 9
16-
const val KeyIndex_Multiply = 12
17-
const val KeyIndex_4 = 4
18-
const val KeyIndex_5 = 5
19-
const val KeyIndex_6 = 6
20-
const val KeyIndex_Minus = 11
5+
// 数字按键
6+
const val KeyIndex_0 = 0
217
const val KeyIndex_1 = 1
228
const val KeyIndex_2 = 2
239
const val KeyIndex_3 = 3
24-
const val KeyIndex_Add = 10
25-
const val KeyIndex_NegativeNumber = 14
26-
const val KeyIndex_0 = 0
27-
const val KeyIndex_Point = 15
28-
const val KeyIndex_Equal = 200
10+
const val KeyIndex_4 = 4
11+
const val KeyIndex_5 = 5
12+
const val KeyIndex_6 = 6
13+
const val KeyIndex_7 = 7
14+
const val KeyIndex_8 = 8
15+
const val KeyIndex_9 = 9
16+
const val KeyIndex_A = 17 // 不按照顺序往下编号是因为在程序员键盘中使用的是 ascii 索引, 而数字 9 和 A 间隔了 7 位
17+
const val KeyIndex_B = 18
18+
const val KeyIndex_C = 19
19+
const val KeyIndex_D = 20
20+
const val KeyIndex_E = 21
21+
const val KeyIndex_F = 22
22+
23+
// 运算按键
24+
const val KeyIndex_Add = 100
25+
const val KeyIndex_Minus = 101
26+
const val KeyIndex_Multiply = 102
27+
const val KeyIndex_Divide = 103
28+
const val KeyIndex_NegativeNumber = 104
29+
const val KeyIndex_Point = 105
30+
const val KeyIndex_Reciprocal = 106
31+
const val KeyIndex_Pow2 = 107
32+
const val KeyIndex_Sqrt = 108
33+
const val KeyIndex_Percentage = 109
34+
const val KeyIndex_Lsh = 110
35+
const val KeyIndex_Rsh = 111
36+
const val KeyIndex_And = 112
37+
const val KeyIndex_Or = 113
38+
const val KeyIndex_Not = 114
39+
const val KeyIndex_NAnd = 115
40+
const val KeyIndex_NOr = 116
41+
const val KeyIndex_XOr = 117
42+
43+
// 功能按键
44+
const val KeyIndex_Equal = 1000
45+
const val KeyIndex_CE = 1001
46+
const val KeyIndex_Clear = 1002
47+
const val KeyIndex_Back = 1003
48+
49+
// 预留按键
50+
const val KeyIndex_Null = -1
51+
2952

3053
val NumberColor = Color.White
3154
val FunctionColor = Color.LightGray
3255
val EqualColor = Color.Cyan
56+
val UnavailableColor = Color.Transparent
3357

3458
val StandardKeyBoardBtn = listOf(
3559
listOf(
3660
KeyBoardData("%", FunctionColor, KeyIndex_Percentage),
3761
KeyBoardData("CE", FunctionColor, KeyIndex_CE),
38-
KeyBoardData("C", FunctionColor, KeyIndex_C),
62+
KeyBoardData("C", FunctionColor, KeyIndex_Clear),
3963
KeyBoardData("", FunctionColor, KeyIndex_Back),
4064
),
4165
listOf(
@@ -70,10 +94,65 @@ val StandardKeyBoardBtn = listOf(
7094
)
7195
)
7296

97+
val ProgrammerKeyBoardBtn = listOf(
98+
listOf(
99+
KeyBoardData("A", NumberColor, KeyIndex_A),
100+
KeyBoardData("XOR", FunctionColor, KeyIndex_XOr),
101+
KeyBoardData("CE", FunctionColor, KeyIndex_CE),
102+
KeyBoardData("C", FunctionColor, KeyIndex_Clear),
103+
KeyBoardData("", FunctionColor, KeyIndex_Back),
104+
),
105+
listOf(
106+
KeyBoardData("B", NumberColor, KeyIndex_B),
107+
KeyBoardData("AND", FunctionColor, KeyIndex_And),
108+
KeyBoardData("OR", FunctionColor, KeyIndex_Or),
109+
KeyBoardData("NOT", FunctionColor, KeyIndex_Not),
110+
KeyBoardData(Operator.Divide.showText, FunctionColor, KeyIndex_Divide),
111+
),
112+
listOf(
113+
KeyBoardData("C", NumberColor, KeyIndex_C),
114+
KeyBoardData("7", NumberColor, KeyIndex_7),
115+
KeyBoardData("8", NumberColor, KeyIndex_8),
116+
KeyBoardData("9", NumberColor, KeyIndex_9),
117+
KeyBoardData(Operator.MULTIPLY.showText, FunctionColor, KeyIndex_Multiply),
118+
),
119+
listOf(
120+
KeyBoardData("D", NumberColor, KeyIndex_D),
121+
KeyBoardData("4", NumberColor, KeyIndex_4),
122+
KeyBoardData("5", NumberColor, KeyIndex_5),
123+
KeyBoardData("6", NumberColor, KeyIndex_6),
124+
KeyBoardData(Operator.MINUS.showText, FunctionColor, KeyIndex_Minus),
125+
),
126+
listOf(
127+
KeyBoardData("E", NumberColor, KeyIndex_E),
128+
KeyBoardData("1", NumberColor, KeyIndex_1),
129+
KeyBoardData("2", NumberColor, KeyIndex_2),
130+
KeyBoardData("3", NumberColor, KeyIndex_3),
131+
KeyBoardData(Operator.ADD.showText, FunctionColor, KeyIndex_Add),
132+
),
133+
listOf(
134+
KeyBoardData("F", NumberColor, KeyIndex_F),
135+
KeyBoardData("<<", FunctionColor, KeyIndex_Lsh),
136+
KeyBoardData("0", NumberColor, KeyIndex_0),
137+
KeyBoardData(">>", FunctionColor, KeyIndex_Rsh),
138+
KeyBoardData("=", FunctionColor, KeyIndex_Equal),
139+
)
140+
)
141+
142+
val BitOperationList = listOf(
143+
Operator.NOT,
144+
Operator.AND,
145+
Operator.OR,
146+
Operator.XOR,
147+
Operator.LSH,
148+
Operator.RSH
149+
)
150+
73151
data class KeyBoardData(
74152
val text: String,
75153
val background: Color,
76-
val clickInfo: Int
154+
val index: Int,
155+
val isAvailable: Boolean = true
77156
)
78157

79158
enum class Operator(val showText: String) {
@@ -83,5 +162,49 @@ enum class Operator(val showText: String) {
83162
Divide("÷"),
84163
SQRT(""),
85164
POW2("²"),
165+
NOT("NOT"),
166+
AND(" AND "),
167+
OR(" OR "),
168+
XOR(" XOR "),
169+
LSH(" Lsh "),
170+
RSH(" Rsh "),
86171
NUll("")
172+
}
173+
174+
enum class InputBase(val number: Int, val forbidBtn: List<Int>) {
175+
HEX(16, listOf()),
176+
DEC(10, listOf(
177+
KeyIndex_A,
178+
KeyIndex_B,
179+
KeyIndex_C,
180+
KeyIndex_D,
181+
KeyIndex_E,
182+
KeyIndex_F
183+
)),
184+
OCT(8, listOf(
185+
KeyIndex_A,
186+
KeyIndex_B,
187+
KeyIndex_C,
188+
KeyIndex_D,
189+
KeyIndex_E,
190+
KeyIndex_F,
191+
KeyIndex_8,
192+
KeyIndex_9,
193+
)),
194+
BIN(2, listOf(
195+
KeyIndex_A,
196+
KeyIndex_B,
197+
KeyIndex_C,
198+
KeyIndex_D,
199+
KeyIndex_E,
200+
KeyIndex_F,
201+
KeyIndex_9,
202+
KeyIndex_8,
203+
KeyIndex_7,
204+
KeyIndex_6,
205+
KeyIndex_5,
206+
KeyIndex_4,
207+
KeyIndex_3,
208+
KeyIndex_2
209+
))
87210
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.equationl.calculator_compose.ui.theme
2+
3+
import androidx.compose.ui.unit.sp
4+
5+
val LargerInputTextSize = 26.sp
6+
val NormalInputTextSize = 20.sp

app/src/main/java/com/equationl/calculator_compose/utils/Utils.kt

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ fun BigDecimal.sqrt(scale: Int): BigDecimal {
3131
/**
3232
* 格式化数字(添加逗号分隔符)
3333
* */
34-
fun String.formatNumber(formatDecimal: Boolean = false, formatInteger: Boolean = true): String {
34+
fun String.formatNumber(
35+
addSplitChar: String = ",",
36+
splitLength: Int = 3,
37+
isAddLeadingZero: Boolean = false,
38+
formatDecimal: Boolean = false,
39+
formatInteger: Boolean = true
40+
): String {
3541
// 如果不是合法数字则不做处理
3642
if (this.substring(0, 1) != "-" && !this.replace(".", "").isDigitsOnly()) return this
3743

@@ -42,7 +48,6 @@ fun String.formatNumber(formatDecimal: Boolean = false, formatInteger: Boolean =
4248
val integer: StringBuilder
4349
val decimal: StringBuilder
4450

45-
4651
if (pointIndex == -1) {
4752
integer = stringBuilder // 整数部分
4853
decimal = StringBuilder() // 小数部分
@@ -54,12 +59,24 @@ fun String.formatNumber(formatDecimal: Boolean = false, formatInteger: Boolean =
5459
decimal.insert(0, '.')
5560
}
5661

62+
var addCharCount = 0
63+
5764
if (formatInteger) {
5865
// 给整数部分添加逗号分隔符
59-
if (integer.length > 3) {
66+
if (integer.length > splitLength) {
6067
val end = if (integer[0] == '-') 2 else 1 // 判断是否有前导符号
61-
for (i in integer.length-3 downTo end step 3) {
62-
integer.insert(i, ",")
68+
for (i in integer.length-splitLength downTo end step splitLength) {
69+
integer.insert(i, addSplitChar)
70+
addCharCount++
71+
}
72+
}
73+
74+
if (isAddLeadingZero) { // 添加前导 0 补满一组
75+
val realLength = integer.length - addCharCount
76+
if (realLength % splitLength != 0) {
77+
repeat(4 - realLength % splitLength) {
78+
integer.insert(0, '0')
79+
}
6380
}
6481
}
6582
}
@@ -80,7 +97,7 @@ fun String.formatNumber(formatDecimal: Boolean = false, formatInteger: Boolean =
8097
}
8198

8299

83-
fun calculate(leftValue: String, rightValue: String, operator: Operator): Result<BigDecimal> {
100+
fun calculate(leftValue: String, rightValue: String, operator: Operator, scale: Int = 16): Result<BigDecimal> {
84101
val left = BigDecimal(leftValue)
85102
val right = BigDecimal(rightValue)
86103

@@ -98,7 +115,7 @@ fun calculate(leftValue: String, rightValue: String, operator: Operator): Result
98115
if (right.signum() == 0) {
99116
return Result.failure(ArithmeticException("除数不能为零"))
100117
}
101-
return Result.success(left.divide(right, 16, RoundingMode.HALF_UP))
118+
return Result.success(left.divide(right, scale, RoundingMode.HALF_UP))
102119
}
103120
Operator.SQRT -> {
104121
if (left.signum() == -1) {
@@ -112,6 +129,14 @@ fun calculate(leftValue: String, rightValue: String, operator: Operator): Result
112129
Operator.NUll -> {
113130
return Result.success(left)
114131
}
132+
Operator.NOT,
133+
Operator.AND,
134+
Operator.OR ,
135+
Operator.XOR,
136+
Operator.LSH,
137+
Operator.RSH -> { // 这些值不会调用这个方法计算,所以直接返回错误
138+
return Result.failure(NumberFormatException("错误的调用"))
139+
}
115140
}
116141
}
117142

0 commit comments

Comments
 (0)