[20191013]oracle number类型存储转化脚本.txt
--//测试看看是否可以利用bc obase=100的输出解决问题。另外以前脚本忘记考虑尾数的四舍五入问题。 --//也许编程就是这样,总有一些细节没有考虑到... --//代码如下num2raw_5.sh:
#! /bin/bash #! number convert oracle raw.
odebug=${ODEBUG:-0}
# process input parameter ,delete "," and all spaces. save to variable v_num. and length to variable v_len. v_num="$*" v_num=${v_num//[, ]/}
# strip e or trailing 0s in decimals or 0000.000 output 0 , v_num=$(echo $v_num/1 + 0 | sed -e "s/[eE]+\?/*10^/" -e "s/^/scale=180;/" | bc | tr -d '\n\\\r' | sed -e "s/\.\([0-9]*[1-9]\)0\+$/.\1/" -e "s/\.0\+$//")
if [[ "$v_num" =~ ^-.*$ ]]; then v_sign=1 v_num=${v_num:1:180} else v_sign=0 fi
if [ $odebug -eq 1 ] ; then echo v_num="$v_num" fi
v_res="" if [ "$v_num" == "0" ]; then v_res="80" echo "$v_res" exit 0 fi
v_pos=$(expr index $v_num ".")
if [ $v_pos -gt 1 ]; then v_exp=$(( v_pos/2 )) elif [ $v_pos -eq 0 ]; then v_exp=$(( (${#v_num}+1) /2 )) elif [ $v_pos -eq 1 ]; then v_tmp1=${v_num:1:180} v_tmp2=$(echo $v_tmp1 | sed 's/^0\+//g') v_exp=$(( (${#v_tmp2} - ${#v_tmp1})/2 )) fi
v_exp1=$(printf "%02x" $(( $v_exp+192 ))) if [ $v_sign -eq 1 ]; then v_exp1=$(printf "%02x" $(( 0xff - 0x${v_exp1} ))) fi
v_res=${v_exp1}${v_res}
# oracle number type max length is 22 bytes (not 22 is 21 bytes??), 1 bytes exponent. # bc不作四舍五入,要加5*10^-41解决问题。 v_tmp=$(echo "scale=180 ; a=$v_num / 100^($v_exp) +5*10^-41; scale=40;a/1 " | bc | tr -d '\n\\\r'| sed -e "s/\.\([0-9]*[1-9]\)0\+$/.\1/" -e "s/\.0\+$//" )
if [ $odebug -eq 1 ] ; then echo v_num="$v_num" v_len="$v_len" v_exp="$v_exp" v_exp1="$v_exp1" v_tmp="$v_tmp" fi
if [ $v_sign -eq 0 ]; then v_res=${v_res}$(echo "obase=100;$v_tmp" | bc | tr -d "." | awk 'BEGIN{RS=" +"}/./{printf ",%02x", $1+1}') else v_res=${v_res}$(echo "obase=100;$v_tmp" | bc | tr -d "." | awk 'BEGIN{RS=" +"}/./{printf ",%02x", 101-$1}') fi
if [ $v_sign -eq 1 -a ${#v_tmp} -lt 40 ]; then v_res=${v_res}",""66" fi
echo "$v_res"
|