Skip to content

Commit

Permalink
new unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
TilmanNeumann committed Dec 27, 2024
1 parent d66900f commit 4dea675
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 26 deletions.
31 changes: 5 additions & 26 deletions src/main/java/de/tilman_neumann/jml/base/BigIntConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a href="https://de.wikipedia.org/wiki/IEEE_754#Allgemeines">https://de.wikipedia.org/wiki/IEEE_754#Allgemeines</a>
Expand All @@ -31,14 +29,16 @@
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
* @return BigInteger
*/
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
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}
48 changes: 48 additions & 0 deletions src/test/java/de/tilman_neumann/jml/base/BigIntConverterTest.java
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/
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));
}
}

0 comments on commit 4dea675

Please sign in to comment.