【问题标题】:dc(1) and leading zerosdc(1) 和前导零
【发布时间】:2011-07-17 05:30:14
【问题描述】:

我有一个 shell 脚本,我用 dc(1) 进行了一些计算。

我需要打印一个带有前导零的数字;我找不到使用 dc 本身执行此操作的简单直接的方法,但手册页确实提到:

Z
从堆栈中弹出一个值,计算位数 它有(或字符数,如果它 是一个字符串)并推动它 数字。 数字计数 数字不包括任何前导 零,即使那些看起来 小数点的右边。

这意味着有一种简单直接的方法......

我知道有无数种方法可以做到这一点,而且我的脚本正在与其中一种一起愉快地运行。我只是好奇;-)

【问题讨论】:

  • 我打算在 bc 中执行它并转储它正在执行的操作,但 GNU bc 没有作为 dc 的前端实现!

标签: bash sh dc


【解决方案1】:

试试这个:

输入:

[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

填充字符串是整体使用的,因此如果所需的长度数大于原始字符串的长度,但小于两个字符串的长度(或整数倍),结果可能会比您要求的要长。

【讨论】:

  • 顺便说一句,这可以通过一堆堆栈交换来完成,而无需使用尽可能多的寄存器,但寄存器更容易。
  • 这是一个很好的答案——虽然比我想象的要复杂一些,但可能是最好的答案。谢谢:-)
【解决方案2】:

这是一个例子,虽然不优雅。这将打印出 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

【讨论】:

    【解决方案3】:

    给出的解决方案适用于十进制数。对于十六进制(以及任何其他输入)基数使用。例如

    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"
    

    GY 是使用的寄存器。首先计算堆栈上的位数,然后是要打印的符号数。

    c=607;  dc <<< "8i${c^^}d0r[r1+r10/d0<G]dsGx f 8+r-[1-[*]nlGx]sY f [d0<Y]dsGxr10op"
    

    【讨论】:

      猜你喜欢
      • 2016-06-27
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多