一、进制
进制是一种数学表示方法,用于表示数字的方式。在计算机科学和电子工程中,进制是一个至关重要的概念,因为计算机使用的是二进制,而人们通常使用的是十进制。本文将介绍四种常见的进制:二进制、八进制、十进制和十六进制,并探讨它们之间的关系和转换。
四种常见进制:
- 二进制(Binary):
- 二进制是由 0 和 1 组成的进制系统。
- 在计算机中,所有的数据都以二进制形式存储和处理。
- 例如,二进制数 101 表示十进制数 5。
- 八进制(Octal):
- 八进制是由 0 到 7 共八个数字组成的进制系统。
- 在计算机领域,八进制常用于表示一组二进制数。
- 例如,八进制数 17 表示十进制数 15。
- 十进制(Decimal):
- 十进制是由 0 到 9 共十个数字组成的进制系统,是人们最常用的进制。
- 在日常生活和数学运算中,我们通常使用十进制来表示数字。
- 例如,十进制数 256 表示 256。
- 十六进制(Hexadecimal):
- 十六进制是由 0 到 9 和 A 到 F 共十六个数字/字母组成的进制系统。
- 在计算机领域,十六进制常用于表示二进制数,便于人们阅读和理解。
- 例如,十六进制数 0xFF 表示十进制数 255。
二、进制转换原理
当我们谈论进制转换时,我们实际上是在改变数字的表示方式,而不是改变数字本身的值。进制转换的原理涉及到数字在不同进制下的表示方式。
- 十进制到其他进制的转换:
- 以十进制数为例,我们通过不断地除以目标进制的基数,然后取余数的方式来进行转换。具体地,我们从待转换的十进制数开始,不断除以目标进制的基数,每次取得的余数就是目标进制中的一位数字。将所有的余数按相反的顺序排列,就得到了目标进制表示的数值。
- 其他进制到十进制的转换:
- 以其他进制数为例,我们通过对每一位数字乘以对应进制的权值,然后相加的方式来进行转换。具体地,我们从待转换的数值的最低位(最右边)开始,每一位数字乘以相应的权值,然后将所有乘积相加,即可得到十进制表示的数值。
- 其他进制到其他进制的转换:
- 为了实现不同进制之间的转换,我们通常会利用十进制作为中间桥梁。我们先将原始数值转换为十进制,然后再将十进制数转换为目标进制。
举例说明:
从十进制到其他进制的转换
例如,将十进制数 100 转换为二进制。我们依次进行除法运算,每次取余数作为二进制的一位,直到商为 0。这个过程如下所示:
100 ÷ 2 = 50 ... 0
50 ÷ 2 = 25 ... 0
25 ÷ 2 = 12 ... 1
12 ÷ 2 = 6 ... 0
6 ÷ 2 = 3 ... 0
3 ÷ 2 = 1 ... 1
1 ÷ 2 = 0 ... 1
然后,我们从下往上读取余数,得到的二进制数为 1100100。
从其他进制到十进制的转换
例如,将二进制数 1101 转换为十进制。我们将每一位数字乘以对应的权值,然后相加,得到的结果如下:
1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 8 + 4 + 0 + 1 = 13
因此,二进制数 1101 对应的十进制数为 13。
三、ConverterFunc 函数详解及注意事项
函数功能
ConverterFunc 函数用于进行进制转换,支持以下功能:
- 任意进制之间的转换。
参数说明:
- 参数格式:ConverterFunc 函数的参数格式为字符串,格式如下:”tobase关键字或输入值 [输入值] [目标进制]”。例如:”tobase 0xFF 8″、”256″、”(1010)”。
- 二进制参数:转换类型为二进制时,输入值需要加上括号。例如,二进制数 (1010) 表示十进制数 10,函数调用应为:ConverterFunc(“(1010)”)。
- 八进制参数:转换类型为八进制时,输入值需要以 “o” 开头。例如,八进制数 o17 表示十进制15,函数调用应为:ConverterFunc(“(o17)”)。
; 调用 ConverterFunc 函数并将参数 "256" 传递给它,然后弹出消息框显示结果
MsgBox ConverterFunc("256") ; 将十进制转换为十六进制
MsgBox ConverterFunc("0xFF") ; 将十六进制转换为十进制
MsgBox ConverterFunc("(1010)") ; 将二进制转换为十进制
MsgBox ConverterFunc("o17") ; 将八进制转换为十进制
MsgBox ConverterFunc("tobase 0xFF 8") ; 将十六进制转换为八进制
MsgBox ConverterFunc("tobase 0xFF 2") ; 将十六进制转换为二进制
MsgBox ConverterFunc("tobase 255 8") ; 将十进制转换为八进制
MsgBox ConverterFunc("tobase 255 2") ; 将十进制转换为二进制
四、函数和类
下面给出上面演示基于的类和函数。
; ConverterFunc 函数用于将数字转换为其他进制表示形式
ConverterFunc(str)
{
; 调用 Converter 类中的 calculateExpression 方法来执行转换,并返回结果
return fullResult := Converter.calculateExpression(str) ; (n < b ? "" : ToBase(n//b,b)) . ((d:=Mod(n,b)) < 10 ? d : Chr(d+55))
}
; Converter 类定义了执行各种运算和转换的方法
class Converter
{
; calculateExpression 方法用于执行各种表达式计算和进制转换
static calculateExpression(rawstr,callflag:=0)
{
; 如果输入的是二进制字符串,先转换为十进制
if (str := RTrim(LTrim(Trim(rawStr), "("), ")")) != Trim(rawStr) and not RegExReplace(str, "[10]", ""){
return result := Utils.otherToTen(str, 2)
;fulltxt := rawStr . "=" . result
;return callflag ? result : fulltxt
}
; 如果输入的是以 o 开头的八进制字符串,先转换为十进制
if inStr(tr := trim(rawStr), "o") == 1 and not RegExReplace((str := subStr(tr, 2)), "\d+", "") {
return result := Utils.otherToTen(str, 8)
;fulltxt := rawStr . "=" . result
;return callflag ? result : fulltxt
}
; 如果输入的是以 0x 开头的十六进制字符串,直接转换为十进制
if inStr(str1 := trim(rawStr), "0x") == 1 and not RegExReplace((str := subStr(str1, 3)), "[a-fA-F\d]+", "") {
result := Format("{1:d}", str1)
fulltxt := rawStr . "=" . result
return result
}
; 如果输入的是纯数字,则将其转换为十六进制
if not RegExReplace((str := trim(rawStr)), "\d+", ""){
result := Utils.tenToOther(str, 16)
fulltxt := rawStr . "=0x" . result
return "0x" . result
}
; 如果输入的是 tobase 命令,则执行任意进制转换
if instr(rawStr, "tobase ") == 1 and (str := Trim(LTrim(rawStr, "tobase "))){
return result := this.tobaseExpression(str)
;fulltxt := rawStr . "=" . result
;return fulltxt
}
}
; tobaseExpression 方法用于执行进制转换
static tobaseExpression(str)
{
; 解析参数
args := strSplit(RegExReplace(trim(str), "\s+", " "), " ")
; 如果参数为两个,执行指定进制的转换
if (args.length == 2) {
tmpMap := Map("2", "(", "8", "o", "16", "0x")
return Utils.mapget(tmpMap, args[2]) . Utils.tenToOther(this.calculateExpression(args[1], 1), args[2]) . (args[2] == "2" ? ")" : "")
}
; 如果参数为三个,执行任意进制之间的转换
else if (args.length == 3) {
return Utils.tenToOther(Utils.otherToTen(args[1], args[2]), args[3])
}
}
}
; Utils 类定义了一些静态方法用于辅助数学计算和进制转换
class Utils
{
; mapget 方法用于获取 Map 中的值
static mapget(map1, key, ignoreCase:=0)
{
try {
if ignoreCase {
; 忽略大小写查找
for k, v in map1 {
if k = key
return v
}
}
return map1.get(key)
}
catch as e {
return ""
}
}
; otherToTen 方法用于将其他进制转换为十进制
static otherToTen(n, b)
{
MI := strLen(n) ; 计算字符串长度
Loop parse, n ; 遍历字符串
result .= A_Loopfield "*" b "^" MI-A_Index "+" ; 构建表达式
return this.polish_notation(rtrim(result, "+")) ; 使用逆波兰表达式计算结果
}
; tenToOther 方法用于将十进制转换为其他进制
static tenToOther(n, b)
{
return (n < b ? "" : this.tenToOther(n // b, b)) . ((d := Mod(n, b)) < 10 ? d : Chr(d + 55))
}
; polish_notation 方法用于计算逆波兰表达式
static polish_notation(expression)
{
operator_list := Map("+", 0, "-", 0, "*", 0, "/", 0, "%", 0, "^", 0) ; 创建运算符列表
operatorlevel_map := Map("(", 0, "+", 1, "-", 1, "*", 2, "/", 2, "%", 2, "^", 3, ")", 4) ; 创建运算符优先级映射
operator_map := Map("+", "add", "-", "sub", "*", "multi", "/", "divi", "%", "mod2", "^", "pow") ; 创建运算符映射
expression := strReplace(strReplace(RegExReplace(trim(expression), "\s+", ""), "**", "^"), "(-", "(0-") ; 格式化表达式
; 获取中缀表达式列表,例如:100+2 -> ["100", "+", "2"]
middlefix_list := [], fix := ""
Loop parse, expression {
current_value := A_LoopField
if (operatorlevel_map.has(current_value)) {
tmp := "" != fix ? middlefix_list.push(fix) : ""
middlefix_list.push(current_value)
fix := ""
} else
fix := fix . current_value
}
tmp2 := fix != "" ? middlefix_list.push(fix) : ""
; 处理开头为负数的情况
if (middlefix_list[1] = "-") {
middlefix_list.insertAt(1, "(")
middlefix_list.insertAt(2, "0")
middlefix_list.insertAt(5, ")")
}
; 转换为后缀表达式(逆波兰表达式)
operator_stack := [], suffix_list := [], number_stack := []
for index, currentElmt in middlefix_list {
if (operator_list.has(currentElmt)) {
while (operator_stack.length > 0 && operatorlevel_map.get(operator_stack.get(operator_stack.Length)) >= operatorlevel_map.get(currentElmt))
suffix_list.push(operator_stack.pop())
operator_stack.push(currentElmt)
} else if (currentElmt = "(")
operator_stack.push("(")
else if (currentElmt = ")") {
while (operator_stack.length > 0 && operatorlevel_map.get(operator_stack.get(operator_stack.length)) > operatorlevel_map.get("("))
suffix_list.push(operator_stack.pop())
if (operator_stack.length > 0)
operator_stack.pop()
} else
suffix_list.push(currentElmt)
}
while (operator_stack.length > 0)
suffix_list.push(operator_stack.pop())
; 计算表达式最终的值
for key, opertor_or_number in suffix_list {
if (operator_list.has(opertor_or_number)) {
number2 := number_stack.pop(), number1 := number_stack.pop()
tmpObj := {add: number1 + number2, sub: number1 - number2, multi: number1 * number2, pow: number1 ** number2}
T1 := opertor_or_number = "/" ? (tmpObj.divi := number1 / number2) : "" ; 处理除法
T2 := opertor_or_number = "%" ? (tmpObj.mod2 := mod(number1, number2)) : "" ; 处理取模
number_stack.push(tmpObj.%operator_map.get(opertor_or_number)%)
} else
number_stack.push(opertor_or_number)
}
return number_stack.pop()
}
}
看看
前来学习
学习一下
学习一下
学习了
感谢分享
学习一下
进来学习
学习
学习一下进制转换
学习一下
学习一下进制转换
为啥评论后还是看不了呢?
学习一下
欢迎
全网就这里有
😁