formatting jslider - Java - formato doble valor como monto en dólares





jlabel ejemplo (5)


Utilice BigDecimal en lugar de doble para los tipos de moneda. En el libro de Java Puzzlers vemos:

System.out.println(2.00 - 1.10);

Y se puede ver que no será 0.9.

String.format () tiene patrones para formatear números.

Necesito formatear el doble "amt" como una cantidad en dólares impresa ("$" + dólares + "." + Centavos) de manera que haya dos dígitos después del decimal.

¿Cuál es la mejor manera de hacerlo?

if (payOrCharge <= 1)
{
    System.out.println("Please enter the payment amount:");
    double amt = keyboard.nextDouble();
    cOne.makePayment(amt);
    System.out.println("-------------------------------");
    System.out.println("The original balance is " + cardBalance + ".");
    System.out.println("You made a payment in the amount of " + amt + ".");
    System.out.println("The new balance is " + (cardBalance - amt) + ".");
}
else if (payOrCharge >= 2)
{
    System.out.println("Please enter the charged amount:");
    double amt = keyboard.nextDouble();
    cOne.addCharge(amt);
    System.out.println("-------------------------------");
    System.out.println("The original balance is $" + cardBalance + ".");
    System.out.println("You added a charge in the amount of " + amt + ".");
    System.out.println("The new balance is " + (cardBalance + amt) + ".");
}



Puedes usar un DecimalFormat

DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(amt));

Eso te dará una impresión con siempre 2dp.

Pero realmente, deberías usar BigDecimal por dinero, debido a problemas de punto flotante




Puedes usar printf para una sola línea

System.out.printf("The original balance is $%.2f.%n", cardBalance);

Esto siempre imprimirá dos decimales, redondeando según sea necesario.




Utilice DecimalFormat para imprimir un valor decimal en el formato deseado, por ejemplo

DecimalFormat dFormat = new DecimalFormat("#.00");
System.out.println("$" + dFormat.format(amt));

Si desea mostrar la cantidad de $ en formato de número de EE. UU., Intente:

DecimalFormat dFormat = new DecimalFormat("####,###,###.00");
System.out.println("$" + dFormat.format(amt));

Utilizando .00 , siempre imprime dos puntos decimales independientemente de su presencia. Si desea imprimir el decimal solo cuando están presentes, use .## en la cadena de formato.




Realicé mi propio análisis de varios de los algoritmos en este hilo y encontré algunos nuevos resultados. Puedes ver esos resultados anteriores en el historial de edición de esta respuesta, pero no son precisos, ya que cometí un error y perdí el tiempo analizando varios algoritmos que no están cerca. Sin embargo, al extraer lecciones de varias respuestas diferentes, ahora tengo dos algoritmos que aplastan al "ganador" de este hilo. Aquí está lo que hago diferente a todos los demás:

// This is faster because a number is divisible by 2^4 or more only 6% of the time
// and more than that a vanishingly small percentage.
while((x & 0x3) == 0) x >>= 2;
// This is effectively the same as the switch-case statement used in the original
// answer. 
if((x & 0x7) != 1) return false;

Sin embargo, esta línea simple, que la mayoría de las veces agrega una o dos instrucciones muy rápidas, simplifica enormemente la switch-casedeclaración en una sola sentencia if. Sin embargo, puede agregarse al tiempo de ejecución si muchos de los números probados tienen factores significativos de poder de dos.

Los algoritmos a continuación son los siguientes:

  • Internet - respuesta publicada de Kip
  • Durron - Mi respuesta modificada utilizando la respuesta de un paso como base
  • DurronTwo - Mi respuesta modificada utilizando la respuesta de dos pasos (por @JohnnyHeggheim), con algunas otras pequeñas modificaciones.

Aquí hay un tiempo de ejecución de muestra si los números se generan usando Math.abs(java.util.Random.nextLong())

 0% Scenario{vm=java, trial=0, benchmark=Internet} 39673.40 ns; ?=378.78 ns @ 3 trials
33% Scenario{vm=java, trial=0, benchmark=Durron} 37785.75 ns; ?=478.86 ns @ 10 trials
67% Scenario{vm=java, trial=0, benchmark=DurronTwo} 35978.10 ns; ?=734.10 ns @ 10 trials

benchmark   us linear runtime
 Internet 39.7 ==============================
   Durron 37.8 ============================
DurronTwo 36.0 ===========================

vm: java
trial: 0

Y aquí hay un tiempo de ejecución de muestra si se ejecuta solo en el primer millón de largos:

 0% Scenario{vm=java, trial=0, benchmark=Internet} 2933380.84 ns; ?=56939.84 ns @ 10 trials
33% Scenario{vm=java, trial=0, benchmark=Durron} 2243266.81 ns; ?=50537.62 ns @ 10 trials
67% Scenario{vm=java, trial=0, benchmark=DurronTwo} 3159227.68 ns; ?=10766.22 ns @ 3 trials

benchmark   ms linear runtime
 Internet 2.93 ===========================
   Durron 2.24 =====================
DurronTwo 3.16 ==============================

vm: java
trial: 0

Como puedes ver, DurronTwofunciona mejor con entradas grandes, porque utiliza el truco de magia muy a menudo, pero se ve superado en comparación con el primer algoritmo y Math.sqrtporque los números son mucho menores. Mientras tanto, el más simple Durrones un gran ganador porque nunca tiene que dividirse por 4 muchas veces en el primer millón de números.

Aquí está Durron:

public final static boolean isPerfectSquareDurron(long n) {
    if(n < 0) return false;
    if(n == 0) return true;

    long x = n;
    // This is faster because a number is divisible by 16 only 6% of the time
    // and more than that a vanishingly small percentage.
    while((x & 0x3) == 0) x >>= 2;
    // This is effectively the same as the switch-case statement used in the original
    // answer. 
    if((x & 0x7) == 1) {

        long sqrt;
        if(x < 410881L)
        {
            int i;
            float x2, y;

            x2 = x * 0.5F;
            y  = x;
            i  = Float.floatToRawIntBits(y);
            i  = 0x5f3759df - ( i >> 1 );
            y  = Float.intBitsToFloat(i);
            y  = y * ( 1.5F - ( x2 * y * y ) );

            sqrt = (long)(1.0F/y);
        } else {
            sqrt = (long) Math.sqrt(x);
        }
        return sqrt*sqrt == x;
    }
    return false;
}

Y DurronTwo

public final static boolean isPerfectSquareDurronTwo(long n) {
    if(n < 0) return false;
    // Needed to prevent infinite loop
    if(n == 0) return true;

    long x = n;
    while((x & 0x3) == 0) x >>= 2;
    if((x & 0x7) == 1) {
        long sqrt;
        if (x < 41529141369L) {
            int i;
            float x2, y;

            x2 = x * 0.5F;
            y = x;
            i = Float.floatToRawIntBits(y);
            //using the magic number from 
            //http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
            //since it more accurate
            i = 0x5f375a86 - (i >> 1);
            y = Float.intBitsToFloat(i);
            y = y * (1.5F - (x2 * y * y));
            y = y * (1.5F - (x2 * y * y)); //Newton iteration, more accurate
            sqrt = (long) ((1.0F/y) + 0.2);
        } else {
            //Carmack hack gives incorrect answer for n >= 41529141369.
            sqrt = (long) Math.sqrt(x);
        }
        return sqrt*sqrt == x;
    }
    return false;
}

Y mi arnés de referencia: (Requiere calibre de Google 0.1-rc5)

public class SquareRootBenchmark {
    public static class Benchmark1 extends SimpleBenchmark {
        private static final int ARRAY_SIZE = 10000;
        long[] trials = new long[ARRAY_SIZE];

        @Override
        protected void setUp() throws Exception {
            Random r = new Random();
            for (int i = 0; i < ARRAY_SIZE; i++) {
                trials[i] = Math.abs(r.nextLong());
            }
        }


        public int timeInternet(int reps) {
            int trues = 0;
            for(int i = 0; i < reps; i++) {
                for(int j = 0; j < ARRAY_SIZE; j++) {
                    if(SquareRootAlgs.isPerfectSquareInternet(trials[j])) trues++;
                }
            }

            return trues;   
        }

        public int timeDurron(int reps) {
            int trues = 0;
            for(int i = 0; i < reps; i++) {
                for(int j = 0; j < ARRAY_SIZE; j++) {
                    if(SquareRootAlgs.isPerfectSquareDurron(trials[j])) trues++;
                }
            }

            return trues;   
        }

        public int timeDurronTwo(int reps) {
            int trues = 0;
            for(int i = 0; i < reps; i++) {
                for(int j = 0; j < ARRAY_SIZE; j++) {
                    if(SquareRootAlgs.isPerfectSquareDurronTwo(trials[j])) trues++;
                }
            }

            return trues;   
        }
    }

    public static void main(String... args) {
        Runner.main(Benchmark1.class, args);
    }
}

ACTUALIZACIÓN: he creado un nuevo algoritmo que es más rápido en algunos escenarios, más lento en otros, he obtenido diferentes puntos de referencia basados ​​en diferentes entradas. Si calculamos módulo 0xFFFFFF = 3 x 3 x 5 x 7 x 13 x 17 x 241, podemos eliminar el 97.82% de los números que no pueden ser cuadrados. Esto se puede (más o menos) hacer en una línea, con 5 operaciones a nivel de bits:

if (!goodLookupSquares[(int) ((n & 0xFFFFFFl) + ((n >> 24) & 0xFFFFFFl) + (n >> 48))]) return false;

El índice resultante es 1) el residuo, 2) el residuo + 0xFFFFFFo 3) el residuo + 0x1FFFFFE. Por supuesto, necesitamos tener una tabla de búsqueda para el módulo de residuos 0xFFFFFF, que se trata de un archivo de 3 mb (en este caso, almacenado como números decimales en texto ASCII, no es óptimo pero claramente mejorable con A ByteBuffery así sucesivamente. No importa mucho. Puede encontrar el archivo aquí (o generarlo usted mismo):

public final static boolean isPerfectSquareDurronThree(long n) {
    if(n < 0) return false;
    if(n == 0) return true;

    long x = n;
    while((x & 0x3) == 0) x >>= 2;
    if((x & 0x7) == 1) {
        if (!goodLookupSquares[(int) ((n & 0xFFFFFFl) + ((n >> 24) & 0xFFFFFFl) + (n >> 48))]) return false;
        long sqrt;
        if(x < 410881L)
        {
            int i;
            float x2, y;

            x2 = x * 0.5F;
            y  = x;
            i  = Float.floatToRawIntBits(y);
            i  = 0x5f3759df - ( i >> 1 );
            y  = Float.intBitsToFloat(i);
            y  = y * ( 1.5F - ( x2 * y * y ) );

            sqrt = (long)(1.0F/y);
        } else {
            sqrt = (long) Math.sqrt(x);
        }
        return sqrt*sqrt == x;
    }
    return false;
}

Lo carga en una booleanmatriz como esta:

private static boolean[] goodLookupSquares = null;

public static void initGoodLookupSquares() throws Exception {
    Scanner s = new Scanner(new File("24residues_squares.txt"));

    goodLookupSquares = new boolean[0x1FFFFFE];

    while(s.hasNextLine()) {
        int residue = Integer.valueOf(s.nextLine());
        goodLookupSquares[residue] = true;
        goodLookupSquares[residue + 0xFFFFFF] = true;
        goodLookupSquares[residue + 0x1FFFFFE] = true;
    }

    s.close();
}

Ejemplo de tiempo de ejecución. Batió Durron(versión uno) en cada prueba que corrí.

 0% Scenario{vm=java, trial=0, benchmark=Internet} 40665.77 ns; ?=566.71 ns @ 10 trials
33% Scenario{vm=java, trial=0, benchmark=Durron} 38397.60 ns; ?=784.30 ns @ 10 trials
67% Scenario{vm=java, trial=0, benchmark=DurronThree} 36171.46 ns; ?=693.02 ns @ 10 trials

  benchmark   us linear runtime
   Internet 40.7 ==============================
     Durron 38.4 ============================
DurronThree 36.2 ==========================

vm: java
trial: 0




java formatting double