diff --git a/src/main/java/de/tilman_neumann/jml/base/BigIntConverter.java b/src/main/java/de/tilman_neumann/jml/base/BigIntConverter.java index 30406e0e..fa364610 100644 --- a/src/main/java/de/tilman_neumann/jml/base/BigIntConverter.java +++ b/src/main/java/de/tilman_neumann/jml/base/BigIntConverter.java @@ -20,8 +20,6 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; -import de.tilman_neumann.util.ConfigUtil; - /** * Conversion from doubles to BigInteger with minimal precision loss and no need of slow BigDecimal. * @see https://de.wikipedia.org/wiki/IEEE_754#Allgemeines @@ -31,6 +29,8 @@ public class BigIntConverter { private static final Logger LOG = LogManager.getLogger(BigIntConverter.class); + private static final boolean DEBUG = false; + /** * Create a BigInteger from double, with minimal precision loss. * @param d @@ -38,7 +38,7 @@ public class BigIntConverter { */ public static BigInteger fromDouble(double d) { long dblBitRep = Double.doubleToRawLongBits(d); - //LOG.debug("bits = " + bitString(dblBitRep)); + if (DEBUG) LOG.debug("bits = " + bitString(dblBitRep)); // Following the wikipedia page: x = s*m*2^e (with base b=2 in IEEE 754) // bit 63 represents the sign s @@ -67,7 +67,7 @@ public static BigInteger fromDouble(double d) { */ public static BigInteger fromDoubleMulPow2(double d, int e2) { long dblBitRep = Double.doubleToRawLongBits(d); - //LOG.debug("bits = " + bitString(dblBitRep)); + if (DEBUG) LOG.debug("bits = " + bitString(dblBitRep)); // Following the wikipedia page: x = s*m*2^e (with base b=2 in IEEE 754) // bit 63 represents the sign s @@ -88,37 +88,16 @@ public static BigInteger fromDoubleMulPow2(double d, int e2) { return (isNegative) ? result.negate() : result; } - @SuppressWarnings("unused") private static String bitString(long l) { String str = ""; long mask = 0x8000000000000000L; for (int i=63; i>=0; i--) { long bit = l & mask; - //LOG.debug("bit = " + bit); + if (DEBUG) LOG.trace("bit = " + bit); str += bit!=0 ? "1" : "0"; if (i==63 || i==52) str += "|"; mask >>>= 1; // unsigned shift -> shifts "0" into leftmost position } return str; } - - private static void test(double d) { - LOG.info(d + " -> " + fromDouble(d)); - } - - private static void test(double d, int e2) { - LOG.info(d + " * 2^" + e2 + " -> " + fromDoubleMulPow2(d, e2)); - } - - public static void main(String[] args) { - ConfigUtil.initProject(); - test(2); - test(3); - test(Math.PI); - test(5.99); - test(6.0001); - test(-6.0001); - test(-6.333, 4); - test(101.333, -4); - } } diff --git a/src/test/java/de/tilman_neumann/jml/base/BigIntConverterTest.java b/src/test/java/de/tilman_neumann/jml/base/BigIntConverterTest.java new file mode 100644 index 00000000..1353440b --- /dev/null +++ b/src/test/java/de/tilman_neumann/jml/base/BigIntConverterTest.java @@ -0,0 +1,48 @@ +/* + * java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project. + * Copyright (C) 2018-2024 Tilman Neumann - tilman.neumann@web.de + * + * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; + * if not, see . + */ +package de.tilman_neumann.jml.base; + +import java.math.BigInteger; + +import org.junit.Before; +import org.junit.Test; + +import de.tilman_neumann.util.ConfigUtil; + +import static de.tilman_neumann.jml.base.BigIntConstants.*; +import static org.junit.Assert.assertEquals; + +public class BigIntConverterTest { + + @Before + public void setup() { + ConfigUtil.initProject(); + } + + @Test + public void testFromDouble() { + assertEquals(I_2, BigIntConverter.fromDouble(2)); + assertEquals(I_3, BigIntConverter.fromDouble(3)); + assertEquals(I_3, BigIntConverter.fromDouble(Math.PI)); + assertEquals(I_5, BigIntConverter.fromDouble(5.99)); + assertEquals(I_6, BigIntConverter.fromDouble(6.0001)); + assertEquals(I_6.negate(), BigIntConverter.fromDouble(-6.0001)); + } + + @Test + public void testFromDoubleMulPow2() { + assertEquals(BigInteger.valueOf(-101), BigIntConverter.fromDoubleMulPow2(-6.333, 4)); + assertEquals(I_6, BigIntConverter.fromDoubleMulPow2(101.333, -4)); + } +}