Scala 和 Java BigDecimal
我想将应用程序中基于数学的模块从 Java 切换为脚本语言。这是由于 mathy Java 的可读性和功能限制。
例如,在 Java 中我有这个:
BigDecimal x = new BigDecimal("1.1");
BigDecimal y = new BigDecimal("1.1");
BigDecimal z = x.multiply(y.exp(new BigDecimal("2"));
如您所见,如果没有 BigDecimal 运算符重载,简单的公式很快就会变得复杂。
对于双打,这看起来不错,但我需要精度。
我希望在 Scala 中我可以做到这一点:
var x = 1.1;
var y = 0.1;
print(x + y);
默认情况下我会得到类似十进制的行为,可惜 Scala 默认情况下不使用十进制计算。
然后我在 Scala 中执行此操作:
var x = BigDecimal(1.1);
var y = BigDecimal(0.1);
println(x + y);
但我仍然得到不精确的结果。
我在 Scala 中是否有什么做得不对的地方?
也许我应该使用 Groovy 来最大化可读性(它默认使用小数)?
I want to switch from Java to a scripting language for the Math based modules in my app. This is due to the readability, and functional limitations of mathy Java.
For e.g, in Java I have this:
BigDecimal x = new BigDecimal("1.1");
BigDecimal y = new BigDecimal("1.1");
BigDecimal z = x.multiply(y.exp(new BigDecimal("2"));
As you can see, without BigDecimal operator overloading, simple formulas get complicated real quick.
With doubles, this looks fine, but I need the precision.
I was hoping in Scala I could do this:
var x = 1.1;
var y = 0.1;
print(x + y);
And by default I would get decimal-like behaviour, alas Scala doesn't use decimal calculation by default.
Then I do this in Scala:
var x = BigDecimal(1.1);
var y = BigDecimal(0.1);
println(x + y);
And I still get an imprecise result.
Is there something I am not doing right in Scala?
Maybe I should use Groovy to maximise readability (it uses decimals by default)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我不知道 Scala,但在 Java 中
new BigDecimal(1.1)
使用double
值初始化BigDecimal
,因此它不是 恰好等于1.1。在 Java 中,您必须使用 new BigDecimal("1.1") 来代替。也许这对 Scala 也有帮助。I don't know Scala, but in Java
new BigDecimal(1.1)
initializes theBigDecimal
with adouble
value and thus it is not exactly equal to 1.1. In Java you have to usenew BigDecimal("1.1")
instead. Maybe that will help in Scala as well.将您的 Scala 代码更改为:
它将像在 Java 中一样工作。
Change your Scala code to this:
and it will work just like it does in Java.
Scala 在这方面与 Java 绝对是一样的。
根据 Joachim 的回答,编写
val x = BigDecimal(1.1)
相当于编写
The Problem, 当然,是 Double
d
已经有舍入误差,所以你正在用错误数据初始化 x。使用接受字符串的构造函数,一切都会好起来的。
根据您的示例,您最好使用
val
而不是var
,并且您也可以在 Scala 中安全地保留分号。Scala is most definitely the same as Java in this respect.
As per Joachim's answer, writing
val x = BigDecimal(1.1)
is equivalent to writing
The problem, of course, is that the Double
d
ALREADY has the rounding error, so you're initialising x with bad data.Use the constructor that accepts a string instead, and all will be fine.
Given your example, you'd also be better off using
val
s instead ofvar
s, and you can safely leave the semicolons off in Scala as well.您可以在内部将值存储为整数/字符串(不带精度)并使用
scale
(这是 Scala REPL 的转录):或者如果您想解析字符串,您可以控制舍入:
You can store values as Integer/String (without precision) internally and use
scale
(this is a transcript from Scala REPL):Or if you want to parse a string, you can control rounding:
我知道这个问题已经很老了并且已经得到解答,但是如果您对不同的语言持开放态度(就像OP似乎那样),另一种选择是使用 Clojure。在我看来,Clojure 有一些最简单的 BigDecimal 数学语法(注意后面的 M - 表示 BigDecimal):
我喜欢 Clojure对于数学来说,因为在许多情况下它默认为精度,例如它使用
Ratio
:I know this question is old and answered, but another option, if you're open to different languages (as the OP seemed to be), would be to use Clojure. Clojure has, IMO, some of the simplest syntax for
BigDecimal
math (note the trailingM
s -- that indicatesBigDecimal
):I like Clojure for math since it defaults to precision in many cases, e.g. its use of
Ratio
: