Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18690795
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-03-21 16:50:41

直接显示未格式化的计算结果是程序员常犯的错误。如果我们沒有将43245435这个数加上一个干分号(数值中每隔三位加上的一个逗号)的话,对使用者而言,他们很难直接读出这个数值的大小。那么请利用下面这个脚本来解決这个问题。

脚本源代码

#!/bin/sh
# nicenumber -- 为加上千分号.
# 如果在数字后有参数,则程序中的DD与TD将会被替代

nicenumber()
{
  # 我们假定在这个脚本中使用者输入的小数点符号为"."。
  # 如果使用者没有特别利用 -d 的参数,改变输出方式,
  # 预设的小数点输出也是"."。

  integer=$(echo $1 | cut -d. -f1)              # left of the decimal
  decimal=$(echo $1 | cut -d. -f2)              # right of the decimal

  if [ $decimal != $1 ]; then
    # There's a fractional part, so let's include it.
    result="${DD:="."}$decimal"
  fi

  thousands=$integer

  while [ $thousands -gt 999 ]; do
    remainder=$(($thousands % 1000))    # 3个数字为一组

    while [ ${#remainder} -lt 3 ] ; do  # force leading zeros as needed
      remainder="0$remainder"
    done

    thousands=$(($thousands / 1000))    # to left of remainder, if any
    result="${TD:=","}${remainder}${result}"    # builds right to left
  done

  nicenum="${thousands}${result}"
  if [ ! -z $2 ] ; then
    echo $nicenum
  fi
}

DD="." # decimal point delimiter, to separate integer and fractional values
TD="," # thousands delimiter, to separate every three digits

while getopts "d:t:" opt; do
  case $opt in
    d ) DD="$OPTARG"    ;;
    t ) TD="$OPTARG"    ;;
  esac
done
shift $(($OPTIND - 1))

if [ $# -eq 0 ] ; then
  echo "Usage: $(basename $0) [-d c] [-t c] numeric value"
  echo "  -d specifies the decimal point delimiter (default '.')"
  echo "  -t specifies the thousands delimiter (default ',')"
  exit 0
fi

nicenumber $1 1         # second arg forces nicenumber to 'echo' output

exit 0

工作原理

函数nicenumber是整个脚本最重要的部分,它主要的工作是将数值一个个的分离,凑足三个即加一个千份号,并将剩下的部分,反复的做上一个动作,直到全部处理完毕为止。

运行脚本

不管你是使用预设或是有增加参数,请给这个程序一个非常大的数字,程序将视需要帮你添加千份号及小数点,并显示计算结果,如下所示:

echo "Do you really want to pay $(nicenumber $price) dollars?"

结果

$ nicenumber 5894625
5,894,625
$ nicenumber 589462532.433
589,462,532.433
$ nicenumber -d, -t. 589462532.433
589.462.532,433

改进与加强

由于不同的国家在使用千份号及其小数点的表示方式各有不同,因此为了让程序更有弹性,我们增加了一个参数。举例来看德国与意大利使用-d "." 与 -t ",". ,法国使用 -d ","与-t" ",还有四种语言的瑞士使用 -d "."与-t "'"。因为有了这些好的例子,我们可以说:这个具有弹性的程序对于使用者而言,是一个相当实用的工具。另一方面,在程序中我来把输入的小数点固定为 ".",如果需要改变这个预设的符号时,大家可以修改两行程式,修改方式如下:

integer=$(echo $1 | cut "-d$DD" -f1)      # 数字的左边
decimal=$(echo $1 | cut "-d$DD" -f2)      # 数字的右边

如果大家输入不同的小数点符号,对目前的程序而言,似乎不尽理想。让大家在输入前即可确认小数点符号,应该是理想的做法,因此我们可以在这两行代码前再增加一小段代码,另外,我们也可以增加 #2中的测试程序,剪下需要的程式码即可:

separator="$(echo $1 | sed 's/[[:digit:]]//g')"
if [ ! -z "$separator" -a "$separator" != "$DD" ] ; then
  echo "$0: Unknown decimal separator $separator encountered." >&2
  exit 1
fi

阅读(652) | 评论(0) | 转发(0) |
0

上一篇:标准化日期格式

下一篇:有效的整数输入

给主人留下些什么吧!~~