-
-
Save anonymous/eabdabea96b7378372f8ff1594811eca to your computer and use it in GitHub Desktop.
Shows inexact calculation issues with double
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package scrap.stackoverflow; | |
import java.math.BigDecimal; | |
import java.math.RoundingMode; | |
public class Inexact { | |
static double roundToTwoPlacesA(double n) { | |
final double m = Math.rint(100 * n); | |
return m / 100.0; | |
} | |
static double roundToTwoPlacesB(double n) { | |
final long m = Math.round(10000000.0 * n); | |
final double x = 0.00001 * m; | |
final long r = (long) Math.rint(x); | |
return r / 100.0; | |
} | |
static double roundToTwoPlacesC(double n) { | |
return BigDecimal.valueOf(n).setScale(2, RoundingMode.HALF_EVEN).doubleValue(); | |
} | |
private static void checkMath(BigDecimal amountB, BigDecimal taxB) { | |
double amountD = amountB.doubleValue(); | |
double taxD = taxB.doubleValue(); | |
BigDecimal rawB = amountB.multiply(taxB); | |
BigDecimal resultB = rawB.setScale(2, RoundingMode.HALF_EVEN); | |
double resultD = roundToTwoPlacesB(amountD * taxD); | |
String strB = resultB.toString(); | |
String strD = BigDecimal.valueOf(resultD).setScale(2).toString(); | |
if (!strB.equals(strD)) { | |
System.out.println("Failed for " + amountB + " * " + taxB + " = " + strB + " vs " + strD); | |
System.out.println("Raw result : " + rawB + ", Double.toString(): " + Double.toString(resultD)); | |
} | |
} | |
public static void main(String[] args) { | |
for (int rateInt = 1; rateInt < 1000; rateInt++) { | |
BigDecimal rate = BigDecimal.ONE.setScale(20).divide(BigDecimal.valueOf(rateInt), RoundingMode.HALF_EVEN); | |
for (int cents = 123456; cents < 123456 + 100000; cents++) { | |
BigDecimal amount = new BigDecimal(cents).scaleByPowerOfTen(-2); | |
checkMath(amount, rate); | |
} | |
} | |
System.out.println("Nothing found..."); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment