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
(但请注意,此函数使用的是中缀符号,而不是前缀)。