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

law*_*ist 3 emacs elisp

以下代码摘录将添加一列数字并生成长度为几位小数的结果.任何人都可以举一个例子,说明如何将结果转换成美元和美分,四舍五入到第二个小数 - 即1.555应该向上舍入到1.56; 并1.554应该向下舍入到1.55.另外,我想在小数点左边每隔三位数插入逗号分隔符 - 例如,1124412.555应该转换为1,124,412.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
Run Code Online (Sandbox Code Playgroud)

根据@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))
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 5

我相信abo-abo (* 0.01 (round (* 100 x)))可能会导致极端情况出现意外(因为0.01无法在内部浮点表示中精确表示).舍入的更简单的解决方案是:

(format "%0.2f" x)
Run Code Online (Sandbox Code Playgroud)