Emacs - 将单行(Mx 计算器)的输出转换为金钱

Emacs - 将单行(Mx 计算器)的输出转换为金钱

Emacs 单行计算器 ( M-x calculator) 是否有内置方法将结果转换为金钱 - 例如转换3335856.73,335,856.70 ?

在使用以下线程中的代码编写我自己的修改之前,我想检查一下是否有人知道可以执行相同操作的内置设置:

https://stackoverflow.com/questions/20100944/how-to-convert-to-dollars-and-cents-rounding-and-with-comma-separators

答案1

编辑(2014 年 2 月 10 日):添加了一个新函数(即lawlist-calculator-update-display),该函数修改了函数calculator-update-display。每次在一系列计算期间更新显示时(例如,在达到总数之前的每个小计),显示现在都会反映最终总数 - 即使用逗号分隔符,删除不需要的额外零,并四舍五入到小数点后第四位。将(message "Copied%s添加to the kill-ring." s)lawlist-calculator-copy

以下修改后的代码最初在屏幕上四舍五入到小数点右边 4 位数字;小数点左边每 3 位数字用逗号分隔符分隔;并且删除小数点右边任何不需要的多余零。

使用该函数lawlist-calculator-copy将会把结果复制到 kill-ring 中 - 四舍五入到小数点右边 2 位数字,并且在小数点左边每 3 位数字包含一个逗号分隔符。

以下是有关四舍五入的文章链接:  http://www.mathsisfun.com/rounding-numbers.html

number-conversion我喜欢的数字转换四舍五入为 5——例如,1.555 将四舍五入为 1.56——@abo-abo编写的函数实现了这一目标。而(format "%0.2f" 1.555)会向下舍入为 1.55,在美国处理货币时可能不应该使用(在我看来)。

(require 'calculator)

(setq calculator-prompt "Calculator:  %s")

(setq calculator-number-digits 4)

(defalias 'calculator-get-prompt 'lawlist-calculator-get-prompt)

(defun lawlist-calculator-get-prompt ()
  "Return a string to display.
The string is set not to exceed the screen width."
  (let* ((calculator-prompt
          (format calculator-prompt
                  (cond
                    ((or calculator-output-radix calculator-input-radix)
                     (if (eq calculator-output-radix
                             calculator-input-radix)
                       (concat
                        (char-to-string
                         (car (rassq calculator-output-radix
                                     calculator-char-radix)))
                        "=")
                       (concat
                        (if calculator-input-radix
                          (char-to-string
                           (car (rassq calculator-input-radix
                                       calculator-char-radix)))
                          "=")
                        (char-to-string
                         (car (rassq calculator-output-radix
                                     calculator-char-radix))))))
                    (calculator-deg "D=")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; REMOVE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                    ;; (t "=="))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; REPLACE WITH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                    (t ""))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
         (prompt
          (concat calculator-prompt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; REMOVE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                  ;; (cdr calculator-stack-display)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; REPLACE WITH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                  (if (floatp (car calculator-stack))
                    (group-number
                      (calculator-remove-zeros
                      ;; round to 4 decimal points
                      ;; The function number conversion will be used when copying.
                        (format "%.4f" (car calculator-stack))))
                    (cdr calculator-stack-display))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                  (cond (calculator-curnum
                         ;; number being typed
                         (concat calculator-curnum "_"))
                        ((and (= 1 (length calculator-stack))
                              calculator-display-fragile)
                         ;; only the result is shown, next number will
                         ;; restart
                         nil)
                        (t
                         ;; waiting for a number or an operator
                         "?"))))
         (trim (- (length prompt) (1- (window-width)))))
    (if (<= trim 0)
      prompt
      (concat calculator-prompt
              (substring prompt (+ trim (length calculator-prompt)))))))

(defalias 'calculator-update-display 'lawlist-calculator-update-display)

(defun lawlist-calculator-update-display (&optional force)
  "Update the display.
If optional argument FORCE is non-nil, don't use the cached string."
  (set-buffer calculator-buffer)
  ;; update calculator-stack-display
  (if (or force
          (not (eq (car calculator-stack-display) calculator-stack)))
    (setq calculator-stack-display
          (cons calculator-stack
                (if calculator-stack
                  (concat
                   (let ((calculator-displayer
                          (if (and calculator-displayers
                                   (= 1 (length calculator-stack)))
                            ;; customizable display for a single value
                            (caar calculator-displayers)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; REMOVE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                            ;; calculator-displayer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; REPLACE WITH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                      (calculator-remove-zeros
                        (group-number
                          (format "%.4f"
                            (string-to-number
                              (calculator-number-to-string calculator-stack)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                            )))
                     (mapconcat 'calculator-number-to-string
                                (reverse calculator-stack)
                                " " ))
                   " "
                   (and calculator-display-fragile
                        calculator-saved-list
                        (= (car calculator-stack)
                           (nth calculator-saved-ptr
                                calculator-saved-list))
                        (if (= 0 calculator-saved-ptr)
                          (format "[%s]" (length calculator-saved-list))
                          (format "[%s/%s]"
                                  (- (length calculator-saved-list)
                                     calculator-saved-ptr)
                                  (length calculator-saved-list)))))
                  ""))))
  (let ((inhibit-read-only t))
    (erase-buffer)
    (insert (calculator-get-prompt)))
  (set-buffer-modified-p nil)
  (if calculator-display-fragile
    (goto-char (1+ (length calculator-prompt)))
    (goto-char (1- (point)))))

(defun lawlist-calculator-copy ()
  "Copy current number to the `kill-ring'."
  (interactive)
  (let ((calculator-displayer
         (or calculator-copy-displayer calculator-displayer))
        (calculator-displayers
         (if calculator-copy-displayer nil calculator-displayers)))
    (calculator-enter)
    ;; remove trailing spaces and an index
    (let (
        (s
          (if (floatp (car calculator-stack))
            (group-number
              (number-conversion
                (format "%s" (car calculator-stack))))
            (cdr calculator-stack-display))) )
      (and s
           (if (string-match "^\\([^ ]+\\) *\\(\\[[0-9/]+\\]\\)? *$" s)
             (setq s (match-string 1 s)))
           (kill-new s)
           (message "Copied `%s` to the kill-ring." s)))))

;; http://stackoverflow.com/a/20101269/2112489
;; @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))

相关内容