如何在 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 位和所有其余的 0s。因此,当单独的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 ClojureClojure 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 中切换科学记数法?的主要内容,如果未能解决你的问题,请参考以下文章

将小数格式化为没有科学记数法的小数位数

如何在 Perl 中转换科学记数法和十进制记数法?

科学记数法如何批量转换成正常的文本或者数字

如何在 seaborn 热图标签中使用科学记数法?

如何在 Pairplot (seaborn) 中使用科学记数法

如何在 Erlang 中使用科学记数法?