如何在 Clojure 中切换科学记数法?
Posted
技术标签:
【中文标题】如何在 Clojure 中切换科学记数法?【英文标题】:How to toggle scientific notation in Clojure? 【发布时间】:2014-05-15 02:38:39 【问题描述】:我正在尝试使用 Clojure 解决 pythonchallenge 问题:
(java.lang.Math/pow 2 38)
我明白了
2.74877906944E11
但是,我需要关闭这个科学记数法。我搜索了clojure docs,仍然不知道该怎么做。在 Clojure 中是否有一种通用的方法来打开/关闭科学记数法?
谢谢。
【问题讨论】:
【参考方案1】:您可以使用format 来控制结果的打印方式。
user> (format "%.0f" (Math/pow 2 38))
"274877906944"
此外,如果不存在丢失所需数据的危险,您可以强制转换为精确类型:
user> 274877906944.0
2.74877906944E11
user> (long 274877906944.0)
274877906944
BigInts 用于更大的输入
user> (bigint 27487790694400000000.0)
27487790694400000000N
【讨论】:
它有效,谢谢!如果我想把一个大数转换成它的科学记数法呢? 它使用 java Formatter docs.oracle.com/javase/7/docs/api/java/util/Formatter.html 的格式 - 所以 %E (带有用于精度控制的可选前缀)。 非常感谢! “%e”确实有效。如果数字不是浮点型,我必须先(float the-number)
。这也是合乎逻辑的。【参考方案2】:
警告
使用java.lang.Math/pow
计算整数的整数幂通常会丢失精度。
例如
(bigint (java.lang.Math/pow 3 38))
; 1350851717672992000N
而
(int-pow 3 38)
; 1350851717672992089
它适用于2
的幂,因为 - 如果您以二进制形式查看它们 - 有一个 1
位和所有其余的 0
s。因此,当单独的1
位在significand 中浮动时,十六进制指数一直在上升。没有精度损失。
顺便说一下,上面的int-pow
只是重复乘法:
(defn int-pow [b ^long ex]
(loop [acc 1, ex ex]
(case ex
0 acc
(recur (* acc b) (dec ex)))))
这更像是一个评论而不是一个解决方案,但不适合这样。
【讨论】:
谢谢。遇到大数计算的时候再来这里参考一下。 @Nick 可以找到温柔的介绍here。标准书籍 Programming Clojure 和 Clojure Programming 很好地涵盖了这个主题 - 值得一读,IMO。但是,不要使用旧版本:一些细节在几年前发生了变化(我认为是 Clojure 版本 1.3)。一切顺利,尽情享受吧! 感谢缩略图。我正在阅读 Clojure 编程(OReilly),这是一本很棒的书。我是编程世界的新手,没有计算机科学背景,所以对我来说有点困难。幸运的是,来自 Clojure 社区的人们非常乐于助人,非常友善 --- 这也给了我很大的鼓励。 好久不见,又找到这个帖子了。我认为这个int-pow
可能更容易阅读:(defn int-pow [base exp] (if (zero? exp) 1N (* base (int-pow base (dec exp)))))
@Nick 是的。它更容易阅读。但它是正确递归的,因此速度较慢,并且仅限于exp
小于 10K 左右,具有正常的 JVM 参数。以上是关于如何在 Clojure 中切换科学记数法?的主要内容,如果未能解决你的问题,请参考以下文章