使用 BigDecimal Java / Kotlin 的表达式

问题描述

我需要了解 Java / Kotlin 的人的帮助。

我想用 BigDecimal 进行一些计算

下面的表达式使用 BigDecimal 会怎样?

(1 + 0.02) ^ (1 / 251) - 1

我尝试这样做:

val x = (BigDecimal.ONE + BigDecimal(0.02)).pow(1/251) - 1

然而,1 除以 251 并不准确,这个表达式总是返回 0

解决方法

数字文字

在构造 BigDecimal 时不要使用数字文字

如果您编写 new BigDecimal( 0.02 ),编译器首先将这样的文字作为 floatdouble 原语进行处理。然后将生成的 floatdouble 传递给通过 BigDecimal 调用的 new 构造函数。

floatdouble 类型基于 floating-point 技术。 Floating-point trades away accuracy 用于性能(快速执行)。

因此,您使用文字会导致不准确,从而破坏了使用 BigDecimal 的两个目的中的第一个:(a) 准确性,以及 (b) 处理非常大/非常小的数字。

因此通过传递文本而不是数字来构造一个 BigDecimal。 Java 语法示例:

new BigDecimal( "0.02" )

使用方法调用,而不是使用 Java 数学运算符

您不能将运算符 +-*/BigDecimal 对象一起使用,至少在 Java 中不能(我不知道 Kotlin)。

要添加 BigDecimal 对象,请调用 plus 方法。要减去,请调用 subtract。等等。 Java 语法示例:

BigDecimal sum = BigDecimal.ONE.plus( new BigDecimal( "0.02" ) ) ;

构造函数

使用 new 构造每个 BigDecimal 对象。您的代码 + BigDecimal(… 应该是 + new BigDecimal(…。好吧,至少在 Java 中……再说一次,我不知道 Kotlin。

示例

你的代码,显然是用 Kotlin 编写的。

val x = (BigDecimal.ONE + BigDecimal(0.02)).pow(1/251) - 1

...应该更像这样,至少在 Java 中(相对于 Kotlin):

BigDecimal sum = BigDecimal.ONE.plus( new BigDecimal( "0.02" ) ) ;
BigDecimal exponent = BigDecimal.ONE.divide( new BigDecimal( "251" ) ;
BigDecimal pow = sum.pow( exponent ) ) ;
BigDecimal subtraction = pow.subtract( BigDecimal.ONE ) ;

请注意,我建议使用多行代码分解数学工作的各个部分。我这样做是为了使代码更易于阅读,并且更易于测试、跟踪和验证。

警告:该代码是现成的,未经测试。而且,我不是数学奇才。

警告:我忽略了四舍五入的问题。您可能想要调用使用 MathContext 来执行舍入的方法的变体,具体取决于您的工作上下文。

,

1 除以 251 是不准确的,这个表达式总是返回 0

这将导致整数除法,要解决整数除法,您可以执行 1.00/251

此外,您还缺少 new 之前的 BigDecimal(0.02),但即使您这样做了,+ 也没有运算符 BigDecimalplus 方法应该使用。