我有一个shell脚本,我用dc(1)做了一些计算。
我需要打印一个带前导零的数字;我无法通过dc本身找到一种简单直接的方法,但是该联机帮助确实提到了:
ž
弹出堆栈中的值,计算位数 它有(或字符数,如果它 是一个字符串)并推动它 数。 a的数字计数 号码不包括任何领先 零,,即使那些出现在 小数点右边。
哪种意味着有一种简单明了的方式......
我知道有很多方法可以实现这一点,而且我的脚本与其中一个很愉快地运行。我只是好奇; - )
答案 0 :(得分:3)
尝试一下:
输入:
[lc1+dsc0nld>b]sb
[sddZdscld>bp]sa
999
12lax
输出:
000000999
输入:
3lax
输出:
999
宏结束后原始编号留在堆栈中。使用的注册:a
(宏),b
(宏),c
(计数),d
(数字)。
说明:
宏a
执行设置,调用b
并打印原始数字。
sd
- 存储要在寄存器d
dZ
- 复制原始数字并按其数字计数dsc
- 复制该计数并将其存储在注册表c
ld>b
- 从注册d
加载所需的数字,如果它大于计数,则调用宏b
p
- 打印原始数字宏b
输出零,直到计数大于所需位数
lc1+
- 从寄存器c
加载计数并将其递增dsc
- 复制计数并将其存储回注册c
0n
- 输出零而不换行ld>b
- 从寄存器d
加载所需的数字,如果它仍然大于增加的计数,则循环返回再次运行宏b
,否则它将返回到调用者(宏a
)使用任意前导字符:
[lclkZ+dsclknld>b]sb
[sksddZdscld>bp]sa
999 14 [ ] lax
999
[abc] 12 [-] lax
---------abc
除了其他寄存器外,它还使用k
来存储字符(实际上可能不止一个):
[XYZ] 6 [def] lax
defXYZ
8 [ab] lax
abababXYZ
4 [ghjikl] lax
ghijklXYZ
填充字符串是全部使用的,因此如果所需的长度数大于原始字符串的长度,但是小于两个字符串的长度(或整数倍),结果可能比您要求的长。< / p>
答案 1 :(得分:0)
这是一个例子,虽然不够优雅。这打印999与2前导零。您需要复制代码以获得更多数字。
#Push number to print on stack
999
# macro to print a zero
[[0]P]sa
# Print a zero if less than 5 digits
dZ5>a
# Print a zero if less than 4 digits
dZ4>a
# Print a zero if less than 3 digits
dZ3>a
# Print a zero if less than 2 digits
dZ2>a
# Print out number
p
答案 2 :(得分:0)
给出的解决方案适用于十进制数字。对于十六进制(以及任何其他输入),使用基数。例如
c=18A; dc <<< "16i${c^^}d0r[r1+r10/d0<G]dsGx4+r-[1-[0]nlGx]sY[d0<Y]dsGxr10op"
^ radix formatted length ^ ^ leading symbol
您也可以尝试
c=19; dc <<< "10i${c^^}d0r[r1+r10/d0<G]dsGx4+r-[1-[_]nlGx]sY[d0<Y]dsGxr10op"
c=607; dc <<< " 8i${c^^}d0r[r1+r10/d0<G]dsGx8+r-[1-[*]nlGx]sY[d0<Y]dsGxr10op"
c=1001; dc <<< " 2i${c^^}d0r[r1+r10/d0<G]dsGx8+r-[1-[ ]nlGx]sY[d0<Y]dsGxr10op"
G
和Y
是使用的寄存器。首先在堆栈上计算位数,然后计算要打印的符号数。
c=607; dc <<< "8i${c^^}d0r[r1+r10/d0<G]dsGx f 8+r-[1-[*]nlGx]sY f [d0<Y]dsGxr10op"