#!/bin/ash
obase=1000000000 # 1e9, the largest power of 10 that fits in int32_t
ibase=$((1 << 7*4)) # only 7 hex digits, because 0xFFFFFFFF > 1e9
inp="000000${1#0x}" # input value in $1 with optional 0x
inp=${inp:$((${#inp}%7)):${#inp}} # pad the string length to a multiple of 7
carry=0
# workaround, since sh and ash don't support arrays
result0=0 # output digits will be stored in resultX variables in little endian
MSDindex=0 # index of the most significant digit in the result
print_result()
{
eval echo -n \$result$MSDindex # print MSD
if [ $MSDindex -gt 0 ]; then # print remaining digits
for i in $(seq $((MSDindex-1)) -1 0); do eval printf "%09d" \$result$i; done
fi
echo
}
# Multiply a digit with the result
# $1 contains the value to multiply with the result array
mul()
{
carry=0
for i in $(seq 0 $MSDindex); do
eval let res="$1\\*result$i+carry"
eval let result$i=res%obase
let carry=res/obase
done
while [ $carry -ne 0 ]; do
let MSDindex=MSDindex+1
eval let result$MSDindex=carry%obase
let carry=carry/obase
done
}
# Add a digit with the result
# $1 contains the digit to add with the array
add()
{
eval let res=$1+result0
eval let result0=res%obase
let carry=res/obase
i=1
while [ $carry -ne 0 ]
do
eval let res=carry+result$i
eval let result$i=res%obase
let carry=res/obase
if [ $i -gt $MSDindex ]; then MSDindex=$i; fi
let i=i+1
done
}
# main conversion loop
while [ -n "$inp" ] # iterate through the hex digits, 7 at a time
do
hexdigit=${inp:0:7}
mul $ibase # result = result*input_base+hexdigit
add 0x$hexdigit
if [ ${#inp} -gt 7 ]; then
inp=${inp: $((7-${#inp}))}
else
unset inp
fi
done
print_result
3条答案
按热度按时间r3i60tvu1#
这是什么shell?在Linux上我看到:
错
错
正确,但输出格式错误
GNU awk
你们有
bc
吗?十六进制值是否需要大写?
嗯,与ksh输出不同。WolframAlpha says
24984864848818840357
我看到busybox有
dc
,但遗憾的是,它是残缺的:nnt7mjpx2#
我曾经尝试用纯sh(实际上是ash,因为
busybox sh
运行内置的ash)编写一个任意精度的十六进制到十进制转换器,它需要比bash多得多的工作量,因为它的特性集有限(没有数组),而且在没有明确文档的情况下会出现“奇怪”的错误(比如表达式中不允许空格)我检查了Ubuntu中的busybox,发现它支持64位算术,因此我需要一个32位的分支来避免乘法时溢出。我选择
1 000 000 000
作为输出基,因为它是32位int中可以表示的10的最大幂。然后输入基需要小于基(需要的进位处理较少),因此我选择0x10000000,这是16的最大次幂,小于100000000当然,如果busybox不支持64位int,那么就必须使用以0x1000为基数的值,同时处理3个十六进制数
用bc确认,每次结果都一样
hs1rzwqc3#
您需要多少位数?
gawk -nM '$++NF = +$_'
足够;-b
:对于字节模式:加快速度-e
:只是为了明确主代码是从命令行获取的如果你只是想得到答案而不需要原始输入,那就更简单了:
一个二个一个一个