dc(1) 和前导零
我有一个 shell 脚本,我用 dc(1) 做了一些计算。
我需要打印一个带有前导零的数字;我找不到一种简单直接的方法来使用 dc 本身执行此操作,但联机帮助页确实提到了:
Z
从堆栈中弹出一个值,计算位数 它有(或字符数,如果它 是一个字符串)并推动它 数字。的数字计数 数字不包括任何前导 零,即使这些看起来 小数点右侧。
这意味着有一种简单而直接的方法......
我知道有无数种方法可以实现这一点,并且我的脚本与其中之一一起运行良好。我只是好奇;-)
I've got a shell script and I do some calculations with dc(1).
I need to have one number printed with leading zeros; I can't find an easy and straightforward way to do this with dc itself, but the manpage does mention:
Z
Pops a value off the stack, calculates the number of digits
it has (or number of characters, if it
is a string) and pushes that
number. The digit count for a
number does not include any leading
zeros, even if those appear to the
right of the radix point.
Which sort of implies there is an easy and straightforward way ...
I know there are a zillion-and-one method of accomplishing this, and I the script is running happily with one of them. I'm just curious ;-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试一下:
输入:
输出:
输入:
输出:
宏结束后,原始数字保留在堆栈中。使用的寄存器:
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
)要使用任意前导字符:
除了其他寄存器之外,它还使用
k
来存储字符(实际上可能不止一个):填充字符串是整个使用的,因此如果所需的长度数字大于字符的长度,结果可能会比您要求的要长原始字符串,但小于两个字符串的长度(或整数倍)。
Give this a try:
Enter:
Output:
Enter:
Output:
The original number is left on the stack after the macro ends. Registers used:
a
(macro),b
(macro),c
(count),d
(digits).Explanation:
Macro
a
does the setup, callsb
and prints the original number.sd
- store the number of digits to be output in registerd
dZ
- duplicate the original number and push the count of its digitsdsc
- duplicate that count and store it in registerc
ld>b
- load the desired digits from registerd
, if it's greater than the count then call macrob
p
- print the original numberMacro
b
outputs zeros until the count is greater than the number of desired digitslc1+
- load the count from registerc
and increment itdsc
- duplicate the count and store it back to registerc
0n
- output a zero without a newlineld>b
- load the desired digits from registerd
, if it's still greater than the incremented count then loop back to run macrob
again, otherwise it will return to the caller (macroa
)To use an arbitrary leading character:
In addition to the other registers, it uses
k
to store the character (which could actually be more than one):The fill strings are used whole so the result may be longer than you asked for if the desired length number is larger than the length of the original string, but smaller than the length of the two strings (or integer multiples).
这是一个例子,尽管不优雅。这将打印出带有 2 个前导零的 999。您需要复制更多数字的代码。
Here is an example, albeit inelegant. This prints out 999 with 2 leading zeros. You'll need to duplicate the code for more digits.
给出的解决方案适用于十进制数。对于十六进制(以及任何其他输入)基数使用。例如,
您也可以尝试使用
G
和Y
作为寄存器。首先计算堆栈上的位数,然后计算要打印的符号数。The solutions given work for decimal numbers. For hex (as well as for any other input) radix use. e.g.
You may also try
G
andY
are the registers used. First the number of digits is counted on the stack, then the number of symbols to be printed.