Emacs 如何转换为美元和美分--四舍五入,并使用逗号分隔符

Emacs 如何转换为美元和美分--四舍五入,并使用逗号分隔符,emacs,elisp,Emacs,Elisp,下面的代码摘录将添加一列数字,并生成几个小数点长的结果。请大家举例说明如何将结果转换成美元和美分,四舍五入到第二个小数点——即,1.555应该四舍五入到1.56;而1.554应该四舍五入到1.55。另外,我想在小数点左边每隔三位插入逗号分隔符——例如,1124412.555应该转换为1124412.56 (let ((sum 0)) (while (re-search-forward "[0-9]*\\.?[0-9]+" nil t) (setq sum (+ sum (string

下面的代码摘录将添加一列数字,并生成几个小数点长的结果。请大家举例说明如何将结果转换成美元和美分,四舍五入到第二个小数点——即,
1.555
应该四舍五入到
1.56
;而
1.554
应该四舍五入到
1.55
。另外,我想在小数点左边每隔三位插入逗号分隔符——例如,
1124412.555
应该转换为
1124412.56

(let ((sum 0))
  (while (re-search-forward "[0-9]*\\.?[0-9]+" nil t)
    (setq sum (+ sum (string-to-number (match-string 0)))))
  (insert "\n\nTotal Hours:  " (format "%s" sum ))
  (insert "\n\nTotal Fee for Services Rendered:  " (format "%s" (* 250 sum)))
  (insert "\n\nOne-third of total fee:  " (format "%s" (/ (* 250 sum) 3))))

2.0
0.2
0.1
4.75
4.0
6.5
0.1

Total Hours:  17.650000000000002

Total Fee for Services Rendered:  4412.500000000001

One-third of total fee:  1470.8333333333337

根据@Drew和@abo abo提供的答案,以下是一份修订草案,目前看来工作正常:

08884.75585
78774.1235
6.545

Total Hours:  87,665.42

Total Fee:  $21,916,356.09

One-Third:  $7,305,452.03

(let ((sum 0))
  (while (re-search-forward "[0-9]*\\.?[0-9]+" nil t)
    (setq sum (+ sum (string-to-number (match-string 0)))))
    (setq total-hours (group-number (number-conversion (format "%s" sum ))))
    (setq services-rendered (group-number (number-conversion (format "%s" (* 250 sum)))))
    (setq one-third (group-number (number-conversion (format "%s" (/ (* 250 sum) 3)))))
  (insert "\n\nTotal Hours:  " total-hours)
  (insert "\n\nTotal Fee:  $" services-rendered)
  (insert "\n\nOne-Third:  $"  one-third) )

;; @abo-abo
(defun number-conversion (str)
  (let ((x (read str)))
    (format "%0.2f" (* 0.01 (round (* 100 x)))) ))

;; http://www.emacswiki.org/emacs/ElispCookbook#toc23
(defun group-number (num &optional size char)
    "Format NUM as string grouped to SIZE with CHAR."
    ;; Based on code for `math-group-float' in calc-ext.el
    (let* ((size (or size 3))
           (char (or char ","))
           (str (if (stringp num)
                    num
                  (number-to-string num)))
           (pt (or (string-match "[^0-9a-zA-Z]" str) (length str))))
      (while (> pt size)
        (setq str (concat (substring str 0 (- pt size))
                          char
                          (substring str (- pt size)))
              pt (- pt size)))
      str))
使用
(格式为“%.2f”您的号码)
。例如:

(insert "\n\nOne-third of total fee:  " (format "%.2f" (/ (* 250 sum) 3))))
f
表示使用小数点表示法。
.2
显示两位小数。请参阅
格式的文档字符串
或Elisp手册的节点
格式字符串

据我所知,在Emacs Lisp中,没有预定义的格式说明符来提供逗号分隔的数字分组。在普通情况下,Lisp
格式
功能更强大(一种语言本身)

如果确实需要逗号分隔,则需要编写解析文本的代码(例如,从
format
返回的字符串),并在需要时插入逗号。也许其他人会费心在这里为你做这件事,但考虑到你目前掌握的信息,你可能可以自己做。没有任何预先定义的东西能神奇地帮助你做到这一点

但逗号可能会有所帮助。

以下是代码:

(defun num->dollars (str)
  (let ((x (read str)))
    (replace-regexp-in-string
     "\\."
     ","
     (format "%0.2f"
             (* 0.01 (round (* 100 x)))))))

(mapcar
 #'num->dollars
 '("4412.500000000001" "1470.8333333333337" "1.555" "1.554"))

 ; => ("4412,50" "1470,83" "1,56" "1,55") 
我相信abo abo的
(*0.01(圆形(*100 x))
在极端情况下会带来惊喜(因为0.01不能在内部浮点表示中精确表示)。四舍五入的更简单解决方案是:

(format "%0.2f" x)

一般来说,在处理货币值(或精度至关重要的其他小数点)时,值得考虑内置的
calc

calc
对浮点数(而不是二进制数)使用十进制表示,因此在处理十进制值时不受经典浮点舍入问题的影响

它还可以对显示的数字进行分组


参见C-hig
(calc)
RET

我认为他想要的逗号是用于分组的。例如,
1234.56
而不是
1234.56
,而不是
1234,56
。注意,不是使用逗号作为小数点,而是用于分组:千,百万,…看起来答案是abo abo(解决了取整问题)和@Drew(解决了逗号问题,引用了EmacsWiki:Elisp Cookbook中的
组号
)的组合。我将整合这些功能并向您汇报。非常感谢你们两位。不知怎的,我没注意到你们也在问取整的问题。我以为你有数字,只是问数字的格式。任务完成了——非常感谢。我已经用一个工作草案更新了这个问题,似乎解决了所有问题——它使用了你从
EmacsWiki:Elisp Cookbook
中提出的
group number
,以及@abo abo(我将其重命名为
number conversion
)提供的
num->dollars
函数。是的,如果有必要使数字精确(这里可能是这样,也可能不是这样,但当数字代表金钱时通常是这样),那么你不应该使用浮点数。非常感谢——我已经更新了问题中的工作草稿,以反映你提供的代码。我试图将@abo abo的函数与你的代码结合起来的尝试没有正确工作。计算(数字转换“4.37”)得到的结果为4.38——正确的结果应为4.37。如果它是4.375、4.376、4.377、4.378或4.379,则只能将其四舍五入到4.38。关于如何修正函数有什么想法吗?我正在使用
(defun数字转换(str)(let((x(read str)))(格式“%0.2f”(+x0.005)))
哦,的确如此<代码>(格式“%0.2f”x)是正确的解决方案,因为%0.2f已经舍入(而不是截断)。
(stefan“1.555”)
似乎没有使用
(defun stefan(str)(let((x(read str)))(格式“%0.2f”x))进行舍入
非常感谢您对
calc
的引用。非常感谢。
calc
中有大量的功能,因此它也很复杂,但有一个非常简单方便的界面,形式为
calc eval
(但请注意,此函数使用的是中缀符号,而不是前缀)。