/* (c) 2016 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wfs.json; /** * Utility class for rounding double values. * * @author Dean Povey * */ public class RoundingUtil { // How to scale the double, indexed by the number of digits private static double[] SCALE = { 1d, 10d, 100d, 1000d, 10000d, 100000d, 1000000d, 10000000d, 100000000d }; /** * Round a value to the specified number of decimal places using the "Round Half Up" strategy. * * <p> * Special cases: * <ul> * <li>NaN is returned as NaN.<li> * <li>+/-Infinity are returned as +/-Infinity. * </ul> * * @param value The value to round * @param numDecimals The number of decimal places to round to. * * @return The value rounded to the specified number of decimals */ public static double round(double value, int numDecimals) { // Technically this code will handle -numDecimals by rounding digits to the left of the decimal point, but that is // probably a use case that is not really needed in practice. double scale = (numDecimals < 8) ? SCALE[numDecimals] : Math.pow(10, numDecimals); // Prevent us exceeding the maximum precision. We make sure the minimum spacing between values is sufficient // for the given scale otherwise just return the value. if (Math.ulp(value) * scale > 1d) return value; return Math.floor(value * scale + 0.5) / scale; } }