使用 kB,MB,GB,... 和 kiB,MiB,GiB 的 ISO 前缀格式化整数,
Posted
技术标签:
【中文标题】使用 kB,MB,GB,... 和 kiB,MiB,GiB 的 ISO 前缀格式化整数,【英文标题】:Formatting an Integer using ISO-prefixes for kB,MB,GB,... and kiB,MiB,GiB, 【发布时间】:2011-04-07 11:51:21 【问题描述】:我正在寻找在大小指示模式下在模式行上打印文件大小的功能。我在源代码中搜索了 size-indication-mode,但找不到对它的代码引用。那么例如打印的功能在哪里 22k
什么时候文件大约有 22 KB 大?
两者之间的区别是什么 - 千字节 (kB)、1000 字节和 - kibibytes (KiB),1024 字节,定义在
Emacs 不应该同时支持吗?
这当然不难写,但为什么要重新发明***呢?
http://en.wikipedia.org/wiki/Kibibyte
【问题讨论】:
【参考方案1】:参见 C-hf format-mode-line
RET 和 C-hv @ 987654322@ RET.
启用size-indication-mode
只会将of %I
添加到缓冲区的本地模式行格式字符串中,其余的由C 函数处理。
您可以改用%i
来查看缓冲区大小(以字节为单位)。
如果您想要一些可以提供任意值的东西,那么 Emacs 提供了至少一个 elisp 函数(在 ls-lisp
模块中):
C-hf ls-lisp-format-file-size
RET
【讨论】:
【参考方案2】:这是我使用的函数。
(defconst number-to-string-approx-suffixes
'("k" "M" "G" "T" "P" "E" "Z" "Y"))
(defun number-to-string-approx-suffix (n &optional binary)
"Return an approximate decimal representation of NUMBER as a string,
followed by a multiplier suffix (k, M, G, T, P, E, Z, Y). The representation
is at most 5 characters long for numbers between 0 and 10^19-5*10^16.
Uses a minus sign if negative.
NUMBER may be an integer or a floating point number.
If the optional argument BINARY is non-nil, use 1024 instead of 1000 as
the base multiplier."
(if (zerop n)
"0"
(let ((sign "")
(b (if binary 1024 1000))
(suffix "")
(bigger-suffixes number-to-string-approx-suffixes))
(if (< n 0)
(setq n (- n)
sign "-"))
(while (and (>= n 9999.5) (consp bigger-suffixes))
(setq n (/ n b) ; TODO: this is rounding down; nearest would be better
suffix (car bigger-suffixes)
bigger-suffixes (cdr bigger-suffixes)))
(concat sign
(if (integerp n)
(int-to-string n)
(number-to-string (floor n)))
suffix))))
我在缓冲区菜单的大小列中使用它。
(defvar Buffer-menu-buffer+size-shorten 'binary)
(defadvice Buffer-menu-buffer+size (before Buffer-menu-shorten-size
compile activate)
"Shorten the size column in a buffer menu by using multiplier suffixes
\(k, M, G, T\).
This is done only if `Buffer-menu-buffer+size-shorten' is non-nil.
If `Buffer-menu-buffer+size-shorten' is the symbol `binary', use binary
multipliers (powers of 1024). Otherwise use decimal (powers of 1000)
multipliers."
(if Buffer-menu-buffer+size-shorten
(let ((binary (eq Buffer-menu-buffer+size-shorten 'binary)))
(save-match-data
(if (string-match "^[0-9]+$" size)
(setq size (number-to-string-approx-suffix (string-to-number size)
binary)))))))
【讨论】:
【参考方案3】:我注意到 emacs dev (bzr) 刚刚定义了一个新功能,file-size-human-readable()
。它正是我所要求的。
一些emacs开发者一定听到了我的呼唤:)
【讨论】:
【参考方案4】:好的,我自己想出了一个解决方案。应该接近size-indication-mode
提供的内容
(defun number-to-iso-postfixed-string (number &optional binary)
"Convert NUMBER to ISO-postfixed string.
If BINARY is non-nil use bibytes prefixes KiB, MiB, GiB instead of
kB, MB, GB etc."
(let ((scale (if binary 1024.0 1000.0))
(postfix nil))
(concat (if (< number scale)
(if (zerop number) "0" (number-to-string number))
(format "%.1f"
(cond ((< number (expt scale 2)) (setq postfix "k") (/ number (expt scale 1)))
((< number (expt scale 3)) (setq postfix "M") (/ number (expt scale 2)))
((< number (expt scale 4)) (setq postfix "G") (/ number (expt scale 3)))
((< number (expt scale 5)) (setq postfix "T") (/ number (expt scale 4)))
((< number (expt scale 6)) (setq postfix "P") (/ number (expt scale 5)))
((< number (expt scale 7)) (setq postfix "E") (/ number (expt scale 6)))
(t
number)
)))
postfix
(when (and postfix binary) "i"))))
;; Use: (number-to-iso-postfixed-string 999 nil)
;; Use: (number-to-iso-postfixed-string 1001 nil)
;; Use: (number-to-iso-postfixed-string 1024)
;; Use: (number-to-iso-postfixed-string 1024 t)
;; Use: (number-to-iso-postfixed-string (* 1024 1024) t)
;; Use: (number-to-iso-postfixed-string (* 1024 1023) t)
;; Use: (number-to-iso-postfixed-string (* 1024 1025) t)
;; Use: (number-to-iso-postfixed-string (* 1024.0 1024 1025) t)
【讨论】:
以上是关于使用 kB,MB,GB,... 和 kiB,MiB,GiB 的 ISO 前缀格式化整数,的主要内容,如果未能解决你的问题,请参考以下文章