java - round - Redondeo un doble a 3 figuras significativas.
redondear double java (5)
¿Cómo puedo redondear un valor doble a 3 cifras significativas?
Usted no puede Los dobles están representando en binario. No tienen decimales para redondear. La única forma en que puede obtener un número específico de lugares decimales es convertirlo a un decimal y dejarlo allí. En el momento en que lo vuelvas a convertir al doble, habrás perdido la precisión decimal nuevamente.
Para todos los fanáticos, aquí y en otros lugares, de convertir a otras radixes y viceversa, o multiplicar y dividir por potencias de diez, muestre el valor doble resultante% 0.001 o lo que sea que exija la precisión requerida, y explique el resultado.
EDITAR: Específicamente, los proponentes de esas técnicas deben explicar la tasa de fallas del 92% del siguiente código:
public class RoundingCounterExample
{
static float roundOff(float x, int position)
{
float a = x;
double temp = Math.pow(10.0, position);
a *= temp;
a = Math.round(a);
return (a / (float)temp);
}
public static void main(String[] args)
{
float a = roundOff(0.0009434f,3);
System.out.println("a="+a+" (a % .0001)="+(a % 0.001));
int count = 0, errors = 0;
for (double x = 0.0; x < 1; x += 0.0001)
{
count++;
double d = x;
int scale = 2;
double factor = Math.pow(10, scale);
d = Math.round(d * factor) / factor;
if ((d % 0.01) != 0.0)
{
System.out.println(d + " " + (d % 0.01));
errors++;
}
}
System.out.println(count + " trials " + errors + " errors");
}
}
¿Alguien sabe cómo puedo redondear un valor doble a 3 cifras significativas como los ejemplos en este sitio web?
Por lo general, no redondeo el número en sí, sino que redondeo la representación de la cadena del número cuando necesito mostrarlo porque generalmente lo que importa es la pantalla, lo que necesita el redondeo (aunque puede que esto no sea cierto en algunas situaciones, y tal vez sea tuyo, pero necesitas elaborar esto si es así). De esta manera, mi número conserva su precisión, pero su visualización es simplificada y más fácil de leer. Para hacer esto, uno puede usar un objeto DecimalFormat, digamos initialzed con una cadena "0.000" ( new DecimalFormat("0.000")
), o use String.format("%.3f", myDouble)
, o varias otras formas.
Por ejemplo:
// yeah, I know this is just Math.PI.
double myDouble = 3.141592653589793;
DecimalFormat myFormat = new DecimalFormat("0.000");
String myDoubleString = myFormat.format(myDouble);
System.out.println("My number is: " + myDoubleString);
// or you can use printf which works like String.format:
System.out.printf("My number is: %.3f%n", myDouble);
Si quieres hacerlo a mano:
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);
}
}
El método anterior redondea un doble a un número deseado de cifras significativas, maneja números negativos y puede indicarse explícitamente que se redondee hacia arriba o hacia abajo
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;
}
double d = ...;
BigDecimal bd = new BigDecimal(d);
bd = bd.round(new MathContext(3));
double rounded = bd.doubleValue();