垂直对齐浮点数在小数点上 [英] Vertical align floats on decimal dot

查看:182
本文介绍了垂直对齐浮点数在小数点上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个简单的方法来对齐浮点数的小数点一列吗?换句话说,我想输出像(竖线'|'只是为了清晰的目的)

  (格式t〜{|〜〜16,5f |〜%〜}'(798573.467 434.543543 2.435 34443.5))



  | 798573.44000 | 
| 434.54355 |
| 2.43500 |
| 34443.50000 |

但尾随空格而不是零,如下所示:

  | 798573.44 | 
| 434.54355 |
| 2.435 |
| 34443.5 |


解决方案

我不认为这可以轻松完成格式的内置控制字符,但是您可以将自己的函数传递给它:

 (declare(ignore colon at))
(destructuring-bind(width digits& optional(pad#空格))args
(let *((string(format nil〜v,vfwidth digits arg))
(非零(位置#\ 0 string:test#'char / = :from-end t))
(dot(position#\。string:test#'char =:from-end t))
(零( - (length string)非零(=非零点)2 1)))
(string(nsubstitute pad#\ 0 string:from-end t:count zeroes)))
(write-string string stream))) )

您可以像这样使用它:

  CL-使用者> (格式t〜{|〜16,5 / my-f / |〜%〜}'(798573.467 434.543543 2.435 34443.5 10))
| 798573.44 |
| 434.54355 |
| 2.435 |
| 34443.5 |
| 10.0 |填充字符默认为#\空格

/ code>,可以像下面这样提供第三个参数:〜16,5,/ my-f /



使用 loop 的替代实现:

 (declare(ignore colon at))
(string with string =(format nil〜v,vf(car args)(cadr args)arg)
和seen-non-zero = nil
(1-(length string))downto 0
as char =(char string i)
如果(char / = char#\0)do(setq seen-non-zero t)
collect(if(and(not seen-non-zero)
(char = char# \0)
(not(char =#\。(char string(1- i)))))
(or(caddr args)#\Space)
char)到字符
finally(write-string(nreverse(coerce chars'string))stream)))

(免责声明:也许我忽略了 format 。)


Is there a simple way to align on the decimal dot a column of floats? In other words, I would like an output like the one of (vertical bars '|' are there only for clarity purpose)

(format t "~{|~16,5f|~%~}" '(798573.467 434.543543 2.435 34443.5))

which is

|    798573.44000|
|       434.54355|
|         2.43500|
|     34443.50000|

but with trailing spaces instead of zeros, as follows:

|    798573.44   |
|       434.54355|
|         2.435  |
|     34443.5    |

解决方案

I do not think that this can easily be done with format's inbuilt control characters, but you could pass your own function to it:

(defun my-f (stream arg colon at &rest args)
  (declare (ignore colon at))
  (destructuring-bind (width digits &optional (pad #\Space)) args
    (let* ((string (format nil "~v,vf" width digits arg))
           (non-zero (position #\0 string :test #'char/= :from-end t))
           (dot (position #\. string :test #'char= :from-end t))
           (zeroes (- (length string) non-zero (if (= non-zero dot) 2 1)))
           (string (nsubstitute pad #\0 string :from-end t :count zeroes)))
      (write-string string stream))))

You can use it like this:

CL-USER> (format t "~{|~16,5/my-f/|~%~}" '(798573.467 434.543543 2.435 34443.5 10))
|    798573.44   |
|       434.54355|
|         2.435  |
|     34443.5    |
|        10.0    |
NIL

The padding character defaults to #\Space, and may be given as a third argument like this: "~16,5,' /my-f/".

An alternative implementation using loop:

(defun my-f (stream arg colon at &rest args)
  (declare (ignore colon at))
  (loop with string = (format nil "~v,vf" (car args) (cadr args) arg)
        and seen-non-zero = nil
        for i from (1- (length string)) downto 0
        as char = (char string i)
        if (char/= char #\0) do (setq seen-non-zero t)
        collect (if (and (not seen-non-zero)
                         (char= char #\0)
                         (not (char= #\. (char string (1- i)))))
                    (or (caddr args) #\Space)
                    char) into chars
        finally (write-string (nreverse (coerce chars 'string)) stream)))

(Disclaimer: Maybe I overlooked something easier in the documentation of format.)

这篇关于垂直对齐浮点数在小数点上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆