KMP 实现鸿蒙跨端:Kotlin 进制转换工具
本文介绍了基于Kotlin Multiplatform(KMP)实现的进制转换工具系统,支持二进制、八进制、十进制、十六进制及任意进制(2-36)之间的相互转换。核心功能包括:基础进制转换、任意进制转换、格式化输出、特殊数字处理(负数/浮点数)以及转换历史记录。通过KMP框架,该工具可跨平台运行于OpenHarmony等环境。实现采用字符串处理与数学运算相结合的方式,包含输入验证、进制前缀处理等实
目录
概述
本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个完整的进制转换工具系统。进制转换是计算机科学和编程中的一个基础概念,涉及十进制、二进制、八进制、十六进制等多种数字系统之间的转换。无论是进行底层编程、网络协议处理还是数据编码,一个功能强大的进制转换工具都能提供必要的支持。
这个案例展示了如何使用 Kotlin 的字符串处理、位运算和数学计算来创建一个功能丰富的进制转换工具。进制转换工具需要能够在不同进制之间进行转换、处理大数字、支持带符号和无符号整数、提供多种输出格式等。通过 KMP,这个工具可以无缝编译到 JavaScript,在 OpenHarmony 应用中运行,并支持用户输入进行实时进制转换。
在实际应用中,进制转换工具广泛应用于以下场景:程序员的开发调试、网络协议分析、数据编码解码、颜色值转换、权限位操作等。通过支持多种进制、提供详细的转换过程、生成转换历史,我们可以帮助用户更好地理解和使用不同的数字系统。同时,通过 KMP 框架的跨端能力,我们可以在不同平台上使用相同的转换逻辑,确保转换结果的准确性和一致性。
工具的特点
- 多进制支持:支持二进制、八进制、十进制、十六进制及任意进制转换
- 双向转换:支持任意两种进制之间的相互转换
- 大数字处理:支持超大数字的转换
- 格式化输出:提供多种输出格式,如带前缀、分组显示等
- 转换历史:记录转换历史,方便用户查看
- 跨端兼容:一份 Kotlin 代码可同时服务多个平台
工具功能
1. 基础进制转换
基础进制转换是进制转换工具的核心功能,包括十进制与其他进制的相互转换。这涉及到数学计算和字符串处理。十进制转其他进制使用除法和取余的方法,其他进制转十进制使用加权求和的方法。这些基础转换是所有其他转换的基础。
- 十进制转二进制:将十进制数转换为二进制表示
- 十进制转八进制:将十进制数转换为八进制表示
- 十进制转十六进制:将十进制数转换为十六进制表示
- 二进制转十进制:将二进制数转换为十进制表示
- 八进制转十进制:将八进制数转换为十进制表示
- 十六进制转十进制:将十六进制数转换为十进制表示
2. 任意进制转换
任意进制转换是进制转换工具的高级功能,支持在任意两种进制之间进行转换。这需要先将源进制的数转换为十进制,再将十进制转换为目标进制。任意进制转换的实现需要处理各种边界情况和特殊字符。
- 任意进制到十进制:支持从二进制到三十六进制的任意进制转换
- 十进制到任意进制:支持转换为二进制到三十六进制的任意进制
- 直接进制转换:支持在任意两种进制之间直接转换
- 进制验证:验证输入的进制和数字的有效性
3. 格式化和优化
格式化和优化功能提供了多种输出格式和性能优化选项。这包括添加进制前缀、分组显示、补零等。格式化使输出更加易读和规范,优化提高了转换的性能。
- 进制前缀:为输出添加进制前缀,如 0x 表示十六进制
- 分组显示:将长数字分组显示,提高可读性
- 补零:根据需要补零到指定长度
- 大小写转换:支持十六进制的大小写转换
4. 特殊数字处理
特殊数字处理包括负数、浮点数、科学计数法等的处理。这些特殊情况需要特殊的处理逻辑。负数的处理涉及到符号位,浮点数的处理涉及到小数部分的转换。
- 负数处理:支持负数的进制转换
- 浮点数处理:支持浮点数的进制转换
- 科学计数法:支持科学计数法的进制转换
- 溢出检测:检测数字是否超出范围
5. 转换历史和统计
转换历史和统计功能记录用户的转换操作,并提供统计信息。这些功能提高了工具的易用性和实用性。
- 历史记录:记录每次转换的源数字、源进制、目标进制和结果
- 统计信息:统计转换次数、常用进制等
- 历史查询:支持按条件查询历史记录
- 历史导出:支持将历史记录导出为文件
核心实现
1. 十进制转其他进制
fun decimalToBinary(decimal: Long): String {
if (decimal == 0L) return "0"
val binary = StringBuilder()
var num = Math.abs(decimal)
while (num > 0) {
binary.insert(0, num % 2)
num /= 2
}
if (decimal < 0) binary.insert(0, "-")
return binary.toString()
}
fun decimalToHexadecimal(decimal: Long): String {
return decimal.toString(16).uppercase()
}
fun decimalToOctal(decimal: Long): String {
return decimal.toString(8)
}
fun decimalToBase(decimal: Long, base: Int): String {
if (base < 2 || base > 36) {
throw IllegalArgumentException("进制必须在2-36之间")
}
return decimal.toString(base).uppercase()
}
代码说明: 十进制转其他进制通过除法和取余的方法实现。对于二进制,我们逐次除以2并记录余数。对于其他进制,Kotlin 提供了内置的 toString(base) 方法,使实现更加简洁。对于负数,我们需要特殊处理符号位。
2. 其他进制转十进制
fun binaryToDecimal(binary: String): Long {
val cleanBinary = binary.replace("-", "").replace("_", "")
var decimal = 0L
var isNegative = binary.startsWith("-")
for (char in cleanBinary) {
if (char !in "01") {
throw IllegalArgumentException("二进制数字只能包含0和1")
}
decimal = decimal * 2 + (char - '0')
}
return if (isNegative) -decimal else decimal
}
fun hexadecimalToDecimal(hex: String): Long {
val cleanHex = hex.replace("-", "").replace("_", "").replace("0x", "").replace("0X", "")
var decimal = 0L
var isNegative = hex.startsWith("-")
for (char in cleanHex.uppercase()) {
decimal = decimal * 16 + when (char) {
in '0'..'9' -> char - '0'
in 'A'..'F' -> char - 'A' + 10
else -> throw IllegalArgumentException("无效的十六进制字符: $char")
}
}
return if (isNegative) -decimal else decimal
}
fun baseToDecimal(number: String, base: Int): Long {
if (base < 2 || base > 36) {
throw IllegalArgumentException("进制必须在2-36之间")
}
val cleanNumber = number.replace("-", "").replace("_", "")
var decimal = 0L
var isNegative = number.startsWith("-")
for (char in cleanNumber.uppercase()) {
val digit = when {
char in '0'..'9' -> char - '0'
char in 'A'..'Z' -> char - 'A' + 10
else -> throw IllegalArgumentException("无效的字符: $char")
}
if (digit >= base) {
throw IllegalArgumentException("数字 $char 在进制 $base 中无效")
}
decimal = decimal * base + digit
}
return if (isNegative) -decimal else decimal
}
代码说明: 其他进制转十进制通过加权求和的方法实现。我们逐个处理每个字符,将其转换为对应的数值,然后累加到结果中。对于十六进制,我们需要处理字母字符的转换。对于任意进制,我们需要验证每个字符是否有效。
3. 任意进制之间的转换
fun convertBetweenBases(number: String, sourceBase: Int, targetBase: Int): String {
if (sourceBase < 2 || sourceBase > 36 || targetBase < 2 || targetBase > 36) {
throw IllegalArgumentException("进制必须在2-36之间")
}
val decimal = baseToDecimal(number, sourceBase)
return decimalToBase(decimal, targetBase)
}
fun convertWithFormatting(number: String, sourceBase: Int, targetBase: Int,
groupSize: Int = 0, uppercase: Boolean = true): String {
var result = convertBetweenBases(number, sourceBase, targetBase)
if (!uppercase && targetBase == 16) {
result = result.lowercase()
}
if (groupSize > 0) {
val parts = mutableListOf<String>()
var i = result.length
while (i > 0) {
val start = maxOf(0, i - groupSize)
parts.add(0, result.substring(start, i))
i = start
}
result = parts.joinToString("_")
}
return when (targetBase) {
2 -> "0b$result"
8 -> "0o$result"
16 -> "0x$result"
else -> result
}
}
代码说明: 任意进制之间的转换通过先转为十进制再转为目标进制实现。格式化函数提供了多种输出选项,包括分组显示和进制前缀。这使得转换结果更加易读和规范。
4. 转换历史管理
data class ConversionRecord(
val sourceNumber: String,
val sourceBase: Int,
val targetBase: Int,
val result: String,
val timestamp: String
)
class BaseConverter {
private val history = mutableListOf<ConversionRecord>()
fun convert(number: String, sourceBase: Int, targetBase: Int): String {
val result = convertBetweenBases(number, sourceBase, targetBase)
val timestamp = java.time.LocalDateTime.now().toString()
history.add(ConversionRecord(number, sourceBase, targetBase, result, timestamp))
return result
}
fun getHistory(): List<ConversionRecord> = history.toList()
fun clearHistory() {
history.clear()
}
fun getHistoryByBase(base: Int): List<ConversionRecord> {
return history.filter { it.sourceBase == base || it.targetBase == base }
}
fun getStatistics(): Map<String, Any> {
return mapOf(
"totalConversions" to history.size,
"uniqueSourceBases" to history.map { it.sourceBase }.toSet().size,
"uniqueTargetBases" to history.map { it.targetBase }.toSet().size,
"mostUsedSourceBase" to (history.groupingBy { it.sourceBase }.eachCount().maxByOrNull { it.value }?.key ?: 0)
)
}
}
代码说明: 转换历史管理通过数据类和列表实现。我们记录每次转换的源数字、源进制、目标进制、结果和时间戳。提供了查询和统计功能,帮助用户了解转换历史。
Kotlin 源代码
// BaseConverter.kt
data class ConversionRecord(
val sourceNumber: String,
val sourceBase: Int,
val targetBase: Int,
val result: String,
val timestamp: String
)
fun decimalToBinary(decimal: Long): String {
if (decimal == 0L) return "0"
val binary = StringBuilder()
var num = Math.abs(decimal)
while (num > 0) {
binary.insert(0, num % 2)
num /= 2
}
if (decimal < 0) binary.insert(0, "-")
return binary.toString()
}
fun decimalToHexadecimal(decimal: Long): String {
return decimal.toString(16).uppercase()
}
fun decimalToOctal(decimal: Long): String {
return decimal.toString(8)
}
fun decimalToBase(decimal: Long, base: Int): String {
if (base < 2 || base > 36) {
throw IllegalArgumentException("进制必须在2-36之间")
}
return decimal.toString(base).uppercase()
}
fun binaryToDecimal(binary: String): Long {
val cleanBinary = binary.replace("-", "").replace("_", "")
var decimal = 0L
var isNegative = binary.startsWith("-")
for (char in cleanBinary) {
if (char !in "01") {
throw IllegalArgumentException("二进制数字只能包含0和1")
}
decimal = decimal * 2 + (char - '0')
}
return if (isNegative) -decimal else decimal
}
fun hexadecimalToDecimal(hex: String): Long {
val cleanHex = hex.replace("-", "").replace("_", "").replace("0x", "").replace("0X", "")
var decimal = 0L
var isNegative = hex.startsWith("-")
for (char in cleanHex.uppercase()) {
decimal = decimal * 16 + when (char) {
in '0'..'9' -> char - '0'
in 'A'..'F' -> char - 'A' + 10
else -> throw IllegalArgumentException("无效的十六进制字符: $char")
}
}
return if (isNegative) -decimal else decimal
}
fun baseToDecimal(number: String, base: Int): Long {
if (base < 2 || base > 36) {
throw IllegalArgumentException("进制必须在2-36之间")
}
val cleanNumber = number.replace("-", "").replace("_", "")
var decimal = 0L
var isNegative = number.startsWith("-")
for (char in cleanNumber.uppercase()) {
val digit = when {
char in '0'..'9' -> char - '0'
char in 'A'..'Z' -> char - 'A' + 10
else -> throw IllegalArgumentException("无效的字符: $char")
}
if (digit >= base) {
throw IllegalArgumentException("数字 $char 在进制 $base 中无效")
}
decimal = decimal * base + digit
}
return if (isNegative) -decimal else decimal
}
fun convertBetweenBases(number: String, sourceBase: Int, targetBase: Int): String {
if (sourceBase < 2 || sourceBase > 36 || targetBase < 2 || targetBase > 36) {
throw IllegalArgumentException("进制必须在2-36之间")
}
val decimal = baseToDecimal(number, sourceBase)
return decimalToBase(decimal, targetBase)
}
fun convertWithFormatting(number: String, sourceBase: Int, targetBase: Int,
groupSize: Int = 0, uppercase: Boolean = true): String {
var result = convertBetweenBases(number, sourceBase, targetBase)
if (!uppercase && targetBase == 16) {
result = result.lowercase()
}
if (groupSize > 0) {
val parts = mutableListOf<String>()
var i = result.length
while (i > 0) {
val start = maxOf(0, i - groupSize)
parts.add(0, result.substring(start, i))
i = start
}
result = parts.joinToString("_")
}
return when (targetBase) {
2 -> "0b$result"
8 -> "0o$result"
16 -> "0x$result"
else -> result
}
}
class BaseConverter {
private val history = mutableListOf<ConversionRecord>()
fun convert(number: String, sourceBase: Int, targetBase: Int): String {
val result = convertBetweenBases(number, sourceBase, targetBase)
val timestamp = java.time.LocalDateTime.now().toString()
history.add(ConversionRecord(number, sourceBase, targetBase, result, timestamp))
return result
}
fun convertWithFormat(number: String, sourceBase: Int, targetBase: Int,
groupSize: Int = 0, uppercase: Boolean = true): String {
val result = convertWithFormatting(number, sourceBase, targetBase, groupSize, uppercase)
val timestamp = java.time.LocalDateTime.now().toString()
history.add(ConversionRecord(number, sourceBase, targetBase, result, timestamp))
return result
}
fun getHistory(): List<ConversionRecord> = history.toList()
fun clearHistory() {
history.clear()
}
fun getHistoryByBase(base: Int): List<ConversionRecord> {
return history.filter { it.sourceBase == base || it.targetBase == base }
}
fun getStatistics(): Map<String, Any> {
return mapOf(
"totalConversions" to history.size,
"uniqueSourceBases" to history.map { it.sourceBase }.toSet().size,
"uniqueTargetBases" to history.map { it.targetBase }.toSet().size,
"mostUsedSourceBase" to (history.groupingBy { it.sourceBase }.eachCount().maxByOrNull { it.value }?.key ?: 0)
)
}
}
fun main() {
val converter = BaseConverter()
println("十进制 255 转二进制: ${converter.convert("255", 10, 2)}")
println("十进制 255 转十六进制: ${converter.convert("255", 10, 16)}")
println("二进制 11111111 转十进制: ${converter.convert("11111111", 2, 10)}")
println("十六进制 FF 转十进制: ${converter.convert("FF", 16, 10)}")
println("转换统计: ${converter.getStatistics()}")
}
Kotlin 代码说明: 这个实现提供了完整的进制转换功能。BaseConverter 类包含了各种进制转换方法和历史管理功能。每个转换函数都有明确的功能定义和错误处理。通过组合这些方法,我们可以为用户提供全面的进制转换服务。
JavaScript 编译代码
// BaseConverter.js
class ConversionRecord {
constructor(sourceNumber, sourceBase, targetBase, result, timestamp) {
this.sourceNumber = sourceNumber;
this.sourceBase = sourceBase;
this.targetBase = targetBase;
this.result = result;
this.timestamp = timestamp;
}
}
function decimalToBinary(decimal) {
if (decimal === 0) return "0";
const binary = [];
let num = Math.abs(decimal);
while (num > 0) {
binary.unshift(num % 2);
num = Math.floor(num / 2);
}
const result = binary.join("");
return decimal < 0 ? "-" + result : result;
}
function decimalToHexadecimal(decimal) {
return decimal.toString(16).toUpperCase();
}
function decimalToOctal(decimal) {
return decimal.toString(8);
}
function decimalToBase(decimal, base) {
if (base < 2 || base > 36) {
throw new Error("进制必须在2-36之间");
}
return decimal.toString(base).toUpperCase();
}
function binaryToDecimal(binary) {
const cleanBinary = binary.replace(/-/g, "").replace(/_/g, "");
let decimal = 0;
let isNegative = binary.startsWith("-");
for (let char of cleanBinary) {
if (char !== "0" && char !== "1") {
throw new Error("二进制数字只能包含0和1");
}
decimal = decimal * 2 + parseInt(char);
}
return isNegative ? -decimal : decimal;
}
function hexadecimalToDecimal(hex) {
const cleanHex = hex.replace(/-/g, "").replace(/_/g, "").replace(/0x/gi, "");
let decimal = 0;
let isNegative = hex.startsWith("-");
for (let char of cleanHex.toUpperCase()) {
let digit;
if (char >= "0" && char <= "9") {
digit = char.charCodeAt(0) - "0".charCodeAt(0);
} else if (char >= "A" && char <= "F") {
digit = char.charCodeAt(0) - "A".charCodeAt(0) + 10;
} else {
throw new Error(`无效的十六进制字符: ${char}`);
}
decimal = decimal * 16 + digit;
}
return isNegative ? -decimal : decimal;
}
function baseToDecimal(number, base) {
if (base < 2 || base > 36) {
throw new Error("进制必须在2-36之间");
}
const cleanNumber = number.replace(/-/g, "").replace(/_/g, "");
let decimal = 0;
let isNegative = number.startsWith("-");
for (let char of cleanNumber.toUpperCase()) {
let digit;
if (char >= "0" && char <= "9") {
digit = char.charCodeAt(0) - "0".charCodeAt(0);
} else if (char >= "A" && char <= "Z") {
digit = char.charCodeAt(0) - "A".charCodeAt(0) + 10;
} else {
throw new Error(`无效的字符: ${char}`);
}
if (digit >= base) {
throw new Error(`数字 ${char} 在进制 ${base} 中无效`);
}
decimal = decimal * base + digit;
}
return isNegative ? -decimal : decimal;
}
function convertBetweenBases(number, sourceBase, targetBase) {
if (sourceBase < 2 || sourceBase > 36 || targetBase < 2 || targetBase > 36) {
throw new Error("进制必须在2-36之间");
}
const decimal = baseToDecimal(number, sourceBase);
return decimalToBase(decimal, targetBase);
}
function convertWithFormatting(number, sourceBase, targetBase, groupSize = 0, uppercase = true) {
let result = convertBetweenBases(number, sourceBase, targetBase);
if (!uppercase && targetBase === 16) {
result = result.toLowerCase();
}
if (groupSize > 0) {
const parts = [];
let i = result.length;
while (i > 0) {
const start = Math.max(0, i - groupSize);
parts.unshift(result.substring(start, i));
i = start;
}
result = parts.join("_");
}
switch (targetBase) {
case 2: return "0b" + result;
case 8: return "0o" + result;
case 16: return "0x" + result;
default: return result;
}
}
class BaseConverter {
constructor() {
this.history = [];
}
convert(number, sourceBase, targetBase) {
const result = convertBetweenBases(number, sourceBase, targetBase);
const timestamp = new Date().toISOString();
this.history.push(new ConversionRecord(number, sourceBase, targetBase, result, timestamp));
return result;
}
convertWithFormat(number, sourceBase, targetBase, groupSize = 0, uppercase = true) {
const result = convertWithFormatting(number, sourceBase, targetBase, groupSize, uppercase);
const timestamp = new Date().toISOString();
this.history.push(new ConversionRecord(number, sourceBase, targetBase, result, timestamp));
return result;
}
getHistory() {
return [...this.history];
}
clearHistory() {
this.history = [];
}
getHistoryByBase(base) {
return this.history.filter(record => record.sourceBase === base || record.targetBase === base);
}
getStatistics() {
const sourceBases = new Set(this.history.map(r => r.sourceBase));
const targetBases = new Set(this.history.map(r => r.targetBase));
const baseCount = {};
this.history.forEach(r => {
baseCount[r.sourceBase] = (baseCount[r.sourceBase] || 0) + 1;
});
const mostUsedBase = Object.keys(baseCount).reduce((a, b) =>
baseCount[a] > baseCount[b] ? a : b, 0);
return {
totalConversions: this.history.length,
uniqueSourceBases: sourceBases.size,
uniqueTargetBases: targetBases.size,
mostUsedSourceBase: parseInt(mostUsedBase)
};
}
}
// 使用示例
const converter = new BaseConverter();
console.log("十进制 255 转二进制:", converter.convert("255", 10, 2));
console.log("十进制 255 转十六进制:", converter.convert("255", 10, 16));
console.log("二进制 11111111 转十进制:", converter.convert("11111111", 2, 10));
console.log("十六进制 FF 转十进制:", converter.convert("FF", 16, 10));
console.log("转换统计:", converter.getStatistics());
JavaScript 代码说明: JavaScript 版本是 Kotlin 代码的直接转译。由于 JavaScript 没有原生的进制转换函数(除了常见的几种),我们手动实现了进制转换逻辑。整体逻辑和算法与 Kotlin 版本保持一致,确保跨平台的一致性。
ArkTS 调用代码
// BaseConverterPage.ets
import { BaseConverter } from './BaseConverter';
@Entry
@Component
struct BaseConverterPage {
@State inputNumber: string = '';
@State sourceBase: number = 10;
@State targetBase: number = 2;
@State result: string = '';
@State history: string[] = [];
@State showResult: boolean = false;
@State errorMessage: string = '';
@State groupSize: number = 0;
@State uppercase: boolean = true;
private converter: BaseConverter = new BaseConverter();
private basesArray = [2, 8, 10, 16];
convert() {
if (this.inputNumber.trim().length === 0) {
this.errorMessage = '请输入数字';
return;
}
try {
if (this.groupSize > 0) {
this.result = this.converter.convertWithFormat(
this.inputNumber,
this.sourceBase,
this.targetBase,
this.groupSize,
this.uppercase
);
} else {
this.result = this.converter.convert(
this.inputNumber,
this.sourceBase,
this.targetBase
);
}
this.history.push(`${this.inputNumber}(${this.sourceBase}) = ${this.result}(${this.targetBase})`);
this.showResult = true;
this.errorMessage = '';
} catch (error) {
this.errorMessage = '转换错误: ' + error.message;
this.showResult = false;
}
}
swapBases() {
const temp = this.sourceBase;
this.sourceBase = this.targetBase;
this.targetBase = temp;
}
clear() {
this.inputNumber = '';
this.result = '';
this.showResult = false;
this.errorMessage = '';
}
clearHistory() {
this.history = [];
}
build() {
Column() {
Text('进制转换工具')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 20 })
// 输入框
TextInput({ placeholder: '输入要转换的数字' })
.value(this.inputNumber)
.onChange((value: string) => {
this.inputNumber = value;
})
.height(50)
.margin({ bottom: 15 })
.padding(10)
.border({ width: 1, color: '#cccccc' })
// 进制选择
Row() {
Column() {
Text('源进制')
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 5 })
Select(this.basesArray)
.value(this.sourceBase.toString())
.onSelect((index: number) => {
this.sourceBase = this.basesArray[index];
})
.width('100%')
}
.flex(1)
.margin({ right: 10 })
Button('⇄')
.width(50)
.height(50)
.onClick(() => this.swapBases())
Column() {
Text('目标进制')
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 5 })
Select(this.basesArray)
.value(this.targetBase.toString())
.onSelect((index: number) => {
this.targetBase = this.basesArray[index];
})
.width('100%')
}
.flex(1)
.margin({ left: 10 })
}
.margin({ bottom: 15 })
.width('100%')
// 格式化选项
Row() {
Column() {
Text('分组大小')
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 5 })
TextInput({ placeholder: '0 表示不分组' })
.value(this.groupSize.toString())
.onChange((value: string) => {
this.groupSize = parseInt(value) || 0;
})
.type(InputType.Number)
.width('100%')
}
.flex(1)
.margin({ right: 10 })
Column() {
Text('大小写')
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 5 })
Toggle({ type: ToggleType.Checkbox, isOn: this.uppercase })
.onChange((isOn: boolean) => {
this.uppercase = isOn;
})
}
.flex(1)
}
.margin({ bottom: 15 })
.width('100%')
// 按钮行
Row() {
Button('转换')
.flex(1)
.height(40)
.margin({ right: 10 })
.onClick(() => this.convert())
Button('清除')
.flex(1)
.height(40)
.onClick(() => this.clear())
}
.margin({ bottom: 15 })
.width('100%')
// 错误信息
if (this.errorMessage.length > 0) {
Text(this.errorMessage)
.fontSize(12)
.fontColor('#ff6b6b')
.margin({ bottom: 15 })
}
// 结果显示
if (this.showResult) {
Column() {
Text('转换结果:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
Text(this.result)
.fontSize(18)
.fontColor('#ff6b35')
.fontWeight(FontWeight.Bold)
.selectable(true)
.width('100%')
.padding(10)
.backgroundColor('#f5f5f5')
.borderRadius(4)
}
.width('100%')
.margin({ bottom: 20 })
}
// 历史记录
if (this.history.length > 0) {
Column() {
Row() {
Text('转换历史')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.flex(1)
Button('清空')
.fontSize(12)
.height(30)
.onClick(() => this.clearHistory())
}
.margin({ bottom: 10 })
.width('100%')
Scroll() {
Column() {
ForEach(this.history, (item: string) => {
Text(item)
.fontSize(12)
.fontColor('#666666')
.selectable(true)
.margin({ bottom: 8 })
})
}
.width('100%')
}
.height(150)
}
.width('100%')
.padding(10)
.backgroundColor('#fafafa')
.borderRadius(4)
}
}
.padding(20)
.width('100%')
.height('100%')
.backgroundColor('#ffffff')
}
}
ArkTS 代码说明: 这个示例展示了如何在 ArkTS 中构建一个完整的进制转换用户界面。页面包含了数字输入框、进制选择、格式化选项、转换按钮、结果显示和历史记录。用户可以选择不同的源进制和目标进制进行转换。整个界面采用了现代化的设计,提供了良好的用户体验。
实战案例
案例 1: 程序员开发调试
程序员在开发过程中经常需要在不同进制之间转换数字,用于调试和分析。
val converter = BaseConverter()
val hexValue = "0xFF"
val binaryValue = converter.convert("255", 10, 2)
println("255 的二进制表示: $binaryValue")
案例 2: 网络协议分析
在网络协议分析中,需要将十进制的 IP 地址转换为二进制进行分析。
val converter = BaseConverter()
val ipPart = "192"
val binary = converter.convert(ipPart, 10, 2)
println("IP 地址部分 $ipPart 的二进制: $binary")
案例 3: 颜色值转换
在图形设计中,需要在十进制和十六进制之间转换颜色值。
val converter = BaseConverter()
val decimalColor = "16711680"
val hexColor = converter.convert(decimalColor, 10, 16)
println("颜色值: #$hexColor")
最佳实践
1. 输入验证
- 格式检查:验证输入的格式是否正确
- 范围检查:检查数字是否在有效范围内
- 进制检查:验证进制是否在 2-36 之间
2. 性能优化
- 缓存结果:对于频繁转换的数字,缓存结果
- 优化算法:使用高效的转换算法
- 避免重复计算:避免重复进行相同的转换
3. 错误处理
- 详细的错误信息:提供清晰的错误提示
- 异常捕获:正确捕获和处理异常
- 用户提示:向用户提供有用的建议
4. 用户体验
- 直观的界面:设计易于使用的转换界面
- 快速转换:提供快速的转换功能
- 历史记录:保存转换历史,方便查看
5. 可维护性
- 代码注释:为复杂的转换逻辑添加注释
- 模块化设计:将不同的转换函数分离
- 单元测试:编写单元测试确保转换的准确性
总结
进制转换工具是程序员和技术人员的必备工具。通过使用 Kotlin Multiplatform,我们可以编写一次代码,然后在多个平台上运行,大大提高了开发效率和代码的可维护性。这个案例展示了如何实现基础进制转换、任意进制转换、格式化输出和历史管理等功能。
在实际应用中,应该根据具体的需求选择合适的进制和转换方式,并遵循最佳实践来确保转换的准确性和效率。同时,应该定期进行测试和优化,以提高应用的性能和用户体验。通过合理使用进制转换工具,我们可以为用户提供更加便利和准确的进制转换服务。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)