> On 21 Dec 2019, at 11:42, Gilles Sadowski <gillese...@gmail.com> wrote:
>
>> ...
>
> So, would you suggest that no "Number"-like class should ever throw
> an exception (but instead return the equivalent of "Double.NaN”)?
Yes. As it was the method could throw for some invalid input and not others.
This is inconsistent. Changing to return a NaN equivalent is more neutral.
Through the rest of the code all the computations that may end up computing NaN
just return NaN. There is no raising of exceptions even when the ISO C99
standard states that an exception may be raised, i.e. these do not throw
ArithmeticException. Removing all exceptions from the class could be stated as
a design decision in the class javadoc. The only exceptions are from the
parse(String) method.
I have been documenting the class using MathJax. This has raised a few more
discrepancies with the c++ standards:
1. Static constructors
Complex:
ofCartesian(x, y)
ofPolar(rho, theta)
No public constructor.
C++
complex(x, y) // This is a public class constructor for type <complex>
polar(rho, theta)
Should we change to the same name, add synonyms or just accept the API
difference?
Sticking to the VALJO design would leave it as is and document that ofPolar
matches the functionality of the ISO C++ polar method.
2. Reciprocal
I had to change the implementation of reciprocal to call divide, effectively:
Complex.ONE.divide(this)
This uses scaling for the divisor and can compute values that the previous
version could not such as:
Complex.ofCartesian(Double.MAX_VALUE, Double.MAX_VALUE).reciprocal()
It also better handles NaN and infinite edge cases.
This method seems redundant. The origin in CM3 was due to Complex implementing
the FieldElement interface. This has reciprocal() as a required method.
It also has multiply(int) hence why that method was originally in the numbers
version of Complex. This has now been dropped as it is redundant with
multiply(double). Since we do not have to support the FieldElement interface I
would suggest dropping reciprocal as well.
3. Equals
Why are there so many static equals functions using
o.a.c.numbers.core.Precision with ULP and deltas?
boolean equals(Complex x, Complex y, int maxUlps)
@return {@code true} if there are fewer than {@code maxUlps} floating
* point values between the real or imaginary, respectively, parts of
{@code x}
* and {@code y}.
boolean equals(Complex x, Complex y)
@return equals(x, y, 1)
boolean equals(Complex x, Complex y, double eps)
@return {@code true} if the values are two adjacent floating point
* numbers or they are within range of each other.
boolean equalsWithRelativeTolerance(Complex x, Complex y, double eps)
{@code true} if the values are two adjacent floating point
* numbers or they are within range of each other.
These are all helper methods. None are required for the test suite. I do not
see the need to have them in the core Complex class. The methods do not cover
all possible ways to measure equality, just some using the Precision class. I
would drop these and leave it to a user to decide how to measure equality.
However I do note that similar methods are in the CM3 Complex class. Leaving
them here would make porting to numbers easy. I think that before the 1.0
release is the time to decide if they should be maintained in Complex, in
another class such as ComplexPrecision for legacy support of porting from CM3,
or dropped. In the later case a note could be added to the package javadoc to
state how to replicate the equals functionality from CM3 using
numbers.Precision.
Alex
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org