Est-ce que quelqu'un sait comment arrondir une valeur double à 3 chiffres significatifs comme les exemples sur ce site
double d = ...;
BigDecimal bd = new BigDecimal(d);
bd = bd.round(new MathContext(3));
double rounded = bd.doubleValue();
public String toSignificantFiguresString(BigDecimal bd, int significantFigures ){
String test = String.format("%."+significantFigures+"G", bd);
if (test.contains("E+")){
test = String.format(Locale.US, "%.0f", Double.valueOf(String.format("%."+significantFigures+"G", bd)));
}
return test;
}
Si vous voulez le faire à la main:
import Java.lang.Math;
public class SigDig {
public static void main(String[] args) {
System.out.println(" -123.456 rounded up to 2 sig figures is " + sigDigRounder(-123.456, 2, 1));
System.out.println(" -0.03394 rounded down to 3 sig figures is " + sigDigRounder(-0.03394, 3, -1));
System.out.println(" 474 rounded up to 2 sig figures is " + sigDigRounder(474, 2, 1));
System.out.println("3004001 rounded down to 4 sig figures is " + sigDigRounder(3004001, 4, -1));
}
public static double sigDigRounder(double value, int nSigDig, int dir) {
double intermediate = value/Math.pow(10,Math.floor(Math.log10(Math.abs(value)))-(nSigDig-1));
if(dir > 0) intermediate = Math.ceil(intermediate);
else if (dir< 0) intermediate = Math.floor(intermediate);
else intermediate = Math.round(intermediate);
double result = intermediate * Math.pow(10,Math.floor(Math.log10(Math.abs(value)))-(nSigDig-1));
return(result);
}
}
La méthode ci-dessus arrondit le double au nombre souhaité de chiffres significatifs, gère les nombres négatifs et peut être explicitement invitée à arrondir vers le haut ou vers le bas
Il n'y a rien de mal à la réponse donnée par Sean Owen ( https://stackoverflow.com/a/7548871/274677 ). Cependant, selon votre cas d'utilisation, vous souhaiterez peut-être arriver à une représentation String. Dans ce cas, IMO, il est préférable de convertir tout en restant dans l'espace BigDecimal en utilisant:
bd.toPlainString();
... si c'est votre cas d'utilisation, vous pourriez être frustré que le code adapté de la réponse d'Owen produise ce qui suit:
d = 0.99, significantDigits = 3 ==> 0.99
... au lieu du 0.990
strictement plus précis.
Si de telles choses sont importantes dans votre cas d'utilisation, je suggère l'adaptation suivante à la réponse d'Owen; vous pouvez évidemment aussi retourner le BigDecimal lui-même au lieu d'appeler toPlainString()
- je le fournis simplement de cette façon pour être complet.
public static String setSignificanDigits(double value, int significantDigits) {
if (significantDigits < 0) throw new IllegalArgumentException();
// this is more precise than simply doing "new BigDecimal(value);"
BigDecimal bd = new BigDecimal(value, MathContext.DECIMAL64);
bd = bd.round(new MathContext(significantDigits, RoundingMode.HALF_UP));
final int precision = bd.precision();
if (precision < significantDigits)
bd = bd.setScale(bd.scale() + (significantDigits-precision));
return bd.toPlainString();
}