blob: c61cfbc3d9f40fd82edd3ded7ee600b615ce1058 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.dfp;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class DfpMathTest {
private DfpField factory;
private Dfp pinf;
private Dfp ninf;
private Dfp nan;
private Dfp qnan;
@Before
public void setUp() {
// Some basic setup. Define some constants and clear the status flags
factory = new DfpField(20);
pinf = factory.newDfp("1").divide(factory.newDfp("0"));
ninf = factory.newDfp("-1").divide(factory.newDfp("0"));
nan = factory.newDfp("0").divide(factory.newDfp("0"));
qnan = factory.newDfp((byte)1, Dfp.QNAN);
ninf.getField().clearIEEEFlags();
// force loading of dfpmath
Dfp pi = factory.getPi();
pi.getField().clearIEEEFlags();
}
@After
public void tearDown() {
pinf = null;
ninf = null;
nan = null;
qnan = null;
}
// Generic test function. Takes params x and y and tests them for
// equality. Then checks the status flags against the flags argument.
// If the test fail, it prints the desc string
private void test(Dfp x, Dfp y, int flags, String desc)
{
boolean b = x.equals(y);
if (!x.equals(y) && !x.unequal(y)) // NaNs involved
b = (x.toString().equals(y.toString()));
if (x.equals(factory.newDfp("0"))) // distinguish +/- zero
b = (b && (x.toString().equals(y.toString())));
b = (b && x.getField().getIEEEFlags() == flags);
if (!b)
Assert.assertTrue("assersion failed "+desc+" x = "+x.toString()+" flags = "+x.getField().getIEEEFlags(), b);
x.getField().clearIEEEFlags();
}
@Test
public void testPow()
{
// Test special cases exponent of zero
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("0")),
factory.newDfp("1"),
0, "pow #1");
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-0")),
factory.newDfp("1"),
0, "pow #2");
test(DfpMath.pow(factory.newDfp("2"), factory.newDfp("0")),
factory.newDfp("1"),
0, "pow #3");
test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-0")),
factory.newDfp("1"),
0, "pow #4");
test(DfpMath.pow(pinf, factory.newDfp("-0")),
factory.newDfp("1"),
0, "pow #5");
test(DfpMath.pow(pinf, factory.newDfp("0")),
factory.newDfp("1"),
0, "pow #6");
test(DfpMath.pow(ninf, factory.newDfp("-0")),
factory.newDfp("1"),
0, "pow #7");
test(DfpMath.pow(ninf, factory.newDfp("0")),
factory.newDfp("1"),
0, "pow #8");
test(DfpMath.pow(qnan, factory.newDfp("0")),
factory.newDfp("1"),
0, "pow #8");
// exponent of one
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1")),
factory.newDfp("0"),
0, "pow #9");
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1")),
factory.newDfp("-0"),
0, "pow #10");
test(DfpMath.pow(factory.newDfp("2"), factory.newDfp("1")),
factory.newDfp("2"),
0, "pow #11");
test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("1")),
factory.newDfp("-2"),
0, "pow #12");
test(DfpMath.pow(pinf, factory.newDfp("1")),
pinf,
0, "pow #13");
test(DfpMath.pow(ninf, factory.newDfp("1")),
ninf,
0, "pow #14");
test(DfpMath.pow(qnan, factory.newDfp("1")),
qnan,
DfpField.FLAG_INVALID, "pow #14.1");
// exponent of NaN
test(DfpMath.pow(factory.newDfp("0"), qnan),
qnan,
DfpField.FLAG_INVALID, "pow #15");
test(DfpMath.pow(factory.newDfp("-0"), qnan),
qnan,
DfpField.FLAG_INVALID, "pow #16");
test(DfpMath.pow(factory.newDfp("2"), qnan),
qnan,
DfpField.FLAG_INVALID, "pow #17");
test(DfpMath.pow(factory.newDfp("-2"), qnan),
qnan,
DfpField.FLAG_INVALID, "pow #18");
test(DfpMath.pow(pinf, qnan),
qnan,
DfpField.FLAG_INVALID, "pow #19");
test(DfpMath.pow(ninf, qnan),
qnan,
DfpField.FLAG_INVALID, "pow #20");
test(DfpMath.pow(qnan, qnan),
qnan,
DfpField.FLAG_INVALID, "pow #21");
// radix of NaN
test(DfpMath.pow(qnan, factory.newDfp("1")),
qnan,
DfpField.FLAG_INVALID, "pow #22");
test(DfpMath.pow(qnan, factory.newDfp("-1")),
qnan,
DfpField.FLAG_INVALID, "pow #23");
test(DfpMath.pow(qnan, pinf),
qnan,
DfpField.FLAG_INVALID, "pow #24");
test(DfpMath.pow(qnan, ninf),
qnan,
DfpField.FLAG_INVALID, "pow #25");
test(DfpMath.pow(qnan, qnan),
qnan,
DfpField.FLAG_INVALID, "pow #26");
// (x > 1) ^ pinf = pinf, (x < -1) ^ pinf = pinf
test(DfpMath.pow(factory.newDfp("2"), pinf),
pinf,
0, "pow #27");
test(DfpMath.pow(factory.newDfp("-2"), pinf),
pinf,
0, "pow #28");
test(DfpMath.pow(pinf, pinf),
pinf,
0, "pow #29");
test(DfpMath.pow(ninf, pinf),
pinf,
0, "pow #30");
// (x > 1) ^ ninf = +0, (x < -1) ^ ninf = +0
test(DfpMath.pow(factory.newDfp("2"), ninf),
factory.getZero(),
0, "pow #31");
test(DfpMath.pow(factory.newDfp("-2"), ninf),
factory.getZero(),
0, "pow #32");
test(DfpMath.pow(pinf, ninf),
factory.getZero(),
0, "pow #33");
test(DfpMath.pow(ninf, ninf),
factory.getZero(),
0, "pow #34");
// (-1 < x < 1) ^ pinf = 0
test(DfpMath.pow(factory.newDfp("0.5"), pinf),
factory.getZero(),
0, "pow #35");
test(DfpMath.pow(factory.newDfp("-0.5"), pinf),
factory.getZero(),
0, "pow #36");
// (-1 < x < 1) ^ ninf = pinf
test(DfpMath.pow(factory.newDfp("0.5"), ninf),
pinf,
0, "pow #37");
test(DfpMath.pow(factory.newDfp("-0.5"), ninf),
pinf,
0, "pow #38");
// +/- 1 ^ +/-inf = NaN
test(DfpMath.pow(factory.getOne(), pinf),
qnan,
DfpField.FLAG_INVALID, "pow #39");
test(DfpMath.pow(factory.getOne(), ninf),
qnan,
DfpField.FLAG_INVALID, "pow #40");
test(DfpMath.pow(factory.newDfp("-1"), pinf),
qnan,
DfpField.FLAG_INVALID, "pow #41");
test(DfpMath.pow(factory.getOne().negate(), ninf),
qnan,
DfpField.FLAG_INVALID, "pow #42");
// +0 ^ +anything except 0, NAN = +0
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1")),
factory.newDfp("0"),
0, "pow #43");
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1e30")),
factory.newDfp("0"),
0, "pow #44");
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1e-30")),
factory.newDfp("0"),
0, "pow #45");
test(DfpMath.pow(factory.newDfp("0"), pinf),
factory.newDfp("0"),
0, "pow #46");
// -0 ^ +anything except 0, NAN, odd integer = +0
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("2")),
factory.newDfp("0"),
0, "pow #47");
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1e30")),
factory.newDfp("0"),
0, "pow #48");
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1e-30")),
factory.newDfp("0"),
DfpField.FLAG_INEXACT, "pow #49");
test(DfpMath.pow(factory.newDfp("-0"), pinf),
factory.newDfp("0"),
0, "pow #50");
// +0 ^ -anything except 0, NAN = +INF
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1")),
pinf,
0, "pow #51");
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1e30")),
pinf,
0, "pow #52");
test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1e-30")),
pinf,
0, "pow #53");
test(DfpMath.pow(factory.newDfp("0"), ninf),
pinf,
0, "pow #54");
// -0 ^ -anything except 0, NAN, odd integer = +INF
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-2")),
pinf,
0, "pow #55");
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1e30")),
pinf,
0, "pow #56");
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1e-30")),
pinf,
DfpField.FLAG_INEXACT, "pow #57");
test(DfpMath.pow(factory.newDfp("-0"), ninf),
pinf,
0, "pow #58");
// -0 ^ -odd integer = -INF
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1")),
ninf,
DfpField.FLAG_INEXACT, "pow #59");
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-12345")),
ninf,
DfpField.FLAG_INEXACT, "pow #60");
// -0 ^ +odd integer = -0
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("3")),
factory.newDfp("-0"),
DfpField.FLAG_INEXACT, "pow #61");
test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("12345")),
factory.newDfp("-0"),
DfpField.FLAG_INEXACT, "pow #62");
// pinf ^ +anything = pinf
test(DfpMath.pow(pinf, factory.newDfp("3")),
pinf,
0, "pow #63");
test(DfpMath.pow(pinf, factory.newDfp("1e30")),
pinf,
0, "pow #64");
test(DfpMath.pow(pinf, factory.newDfp("1e-30")),
pinf,
0, "pow #65");
test(DfpMath.pow(pinf, pinf),
pinf,
0, "pow #66");
// pinf ^ -anything = +0
test(DfpMath.pow(pinf, factory.newDfp("-3")),
factory.getZero(),
0, "pow #67");
test(DfpMath.pow(pinf, factory.newDfp("-1e30")),
factory.getZero(),
0, "pow #68");
test(DfpMath.pow(pinf, factory.newDfp("-1e-30")),
factory.getZero(),
0, "pow #69");
test(DfpMath.pow(pinf, ninf),
factory.getZero(),
0, "pow #70");
// ninf ^ anything = -0 ^ -anything
// ninf ^ -anything except 0, NAN, odd integer = +0
test(DfpMath.pow(ninf, factory.newDfp("-2")),
factory.newDfp("0"),
0, "pow #71");
test(DfpMath.pow(ninf, factory.newDfp("-1e30")),
factory.newDfp("0"),
0, "pow #72");
test(DfpMath.pow(ninf, factory.newDfp("-1e-30")),
factory.newDfp("0"),
DfpField.FLAG_INEXACT, "pow #73");
test(DfpMath.pow(ninf, ninf),
factory.newDfp("0"),
0, "pow #74");
// ninf ^ +anything except 0, NAN, odd integer = +INF
test(DfpMath.pow(ninf, factory.newDfp("2")),
pinf,
0, "pow #75");
test(DfpMath.pow(ninf, factory.newDfp("1e30")),
pinf,
0, "pow #76");
test(DfpMath.pow(ninf, factory.newDfp("1e-30")),
pinf,
DfpField.FLAG_INEXACT, "pow #77");
test(DfpMath.pow(ninf, pinf),
pinf,
0, "pow #78");
// ninf ^ +odd integer = -INF
test(DfpMath.pow(ninf, factory.newDfp("3")),
ninf,
DfpField.FLAG_INEXACT, "pow #79");
test(DfpMath.pow(ninf, factory.newDfp("12345")),
ninf,
DfpField.FLAG_INEXACT, "pow #80");
// ninf ^ -odd integer = -0
test(DfpMath.pow(ninf, factory.newDfp("-3")),
factory.newDfp("-0"),
DfpField.FLAG_INEXACT, "pow #81");
test(DfpMath.pow(ninf, factory.newDfp("-12345")),
factory.newDfp("-0"),
DfpField.FLAG_INEXACT, "pow #82");
// -anything ^ integer
test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("3")),
factory.newDfp("-8"),
DfpField.FLAG_INEXACT, "pow #83");
test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("16")),
factory.newDfp("65536"),
0, "pow #84");
test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-3")),
factory.newDfp("-0.125"),
DfpField.FLAG_INEXACT, "pow #85");
test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-4")),
factory.newDfp("0.0625"),
0, "pow #86");
// -anything ^ noninteger = NaN
test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-4.1")),
qnan,
DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "pow #87");
// Some fractional cases.
test(DfpMath.pow(factory.newDfp("2"),factory.newDfp("1.5")),
factory.newDfp("2.8284271247461901"),
DfpField.FLAG_INEXACT, "pow #88");
}
@Test
public void testSin()
{
test(DfpMath.sin(pinf),
nan,
DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "sin #1");
test(DfpMath.sin(nan),
nan,
DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "sin #2");
test(DfpMath.sin(factory.getZero()),
factory.getZero(),
DfpField.FLAG_INEXACT, "sin #3");
test(DfpMath.sin(factory.getPi()),
factory.getZero(),
DfpField.FLAG_INEXACT, "sin #4");
test(DfpMath.sin(factory.getPi().negate()),
factory.newDfp("-0"),
DfpField.FLAG_INEXACT, "sin #5");
test(DfpMath.sin(factory.getPi().multiply(2)),
factory.getZero(),
DfpField.FLAG_INEXACT, "sin #6");
test(DfpMath.sin(factory.getPi().divide(2)),
factory.getOne(),
DfpField.FLAG_INEXACT, "sin #7");
test(DfpMath.sin(factory.getPi().divide(2).negate()),
factory.getOne().negate(),
DfpField.FLAG_INEXACT, "sin #8");
test(DfpMath.sin(DfpMath.atan(factory.getOne())), // pi/4
factory.newDfp("0.5").sqrt(),
DfpField.FLAG_INEXACT, "sin #9");
test(DfpMath.sin(DfpMath.atan(factory.getOne())).negate(), // -pi/4
factory.newDfp("0.5").sqrt().negate(),
DfpField.FLAG_INEXACT, "sin #10");
test(DfpMath.sin(DfpMath.atan(factory.getOne())).negate(), // -pi/4
factory.newDfp("0.5").sqrt().negate(),
DfpField.FLAG_INEXACT, "sin #11");
test(DfpMath.sin(factory.newDfp("0.1")),
factory.newDfp("0.0998334166468281523"),
DfpField.FLAG_INEXACT, "sin #12");
test(DfpMath.sin(factory.newDfp("0.2")),
factory.newDfp("0.19866933079506121546"),
DfpField.FLAG_INEXACT, "sin #13");
test(DfpMath.sin(factory.newDfp("0.3")),
factory.newDfp("0.2955202066613395751"),
DfpField.FLAG_INEXACT, "sin #14");
test(DfpMath.sin(factory.newDfp("0.4")),
factory.newDfp("0.38941834230865049166"),
DfpField.FLAG_INEXACT, "sin #15");
test(DfpMath.sin(factory.newDfp("0.5")),
factory.newDfp("0.47942553860420300026"), // off by one ULP
DfpField.FLAG_INEXACT, "sin #16");
test(DfpMath.sin(factory.newDfp("0.6")),
factory.newDfp("0.56464247339503535721"), // off by one ULP
DfpField.FLAG_INEXACT, "sin #17");
test(DfpMath.sin(factory.newDfp("0.7")),
factory.newDfp("0.64421768723769105367"),
DfpField.FLAG_INEXACT, "sin #18");
test(DfpMath.sin(factory.newDfp("0.8")),
factory.newDfp("0.71735609089952276163"),
DfpField.FLAG_INEXACT, "sin #19");
test(DfpMath.sin(factory.newDfp("0.9")), // off by one ULP
factory.newDfp("0.78332690962748338847"),
DfpField.FLAG_INEXACT, "sin #20");
test(DfpMath.sin(factory.newDfp("1.0")),
factory.newDfp("0.84147098480789650666"),
DfpField.FLAG_INEXACT, "sin #21");
test(DfpMath.sin(factory.newDfp("1.1")),
factory.newDfp("0.89120736006143533995"),
DfpField.FLAG_INEXACT, "sin #22");
test(DfpMath.sin(factory.newDfp("1.2")),
factory.newDfp("0.93203908596722634968"),
DfpField.FLAG_INEXACT, "sin #23");
test(DfpMath.sin(factory.newDfp("1.3")),
factory.newDfp("0.9635581854171929647"),
DfpField.FLAG_INEXACT, "sin #24");
test(DfpMath.sin(factory.newDfp("1.4")),
factory.newDfp("0.98544972998846018066"),
DfpField.FLAG_INEXACT, "sin #25");
test(DfpMath.sin(factory.newDfp("1.5")),
factory.newDfp("0.99749498660405443096"),
DfpField.FLAG_INEXACT, "sin #26");
test(DfpMath.sin(factory.newDfp("1.6")),
factory.newDfp("0.99957360304150516323"),
DfpField.FLAG_INEXACT, "sin #27");
}
}