2010-08-04 27 views

Respuesta

1

La definición de punto fijo de 32 bits puede variar. La idea general del punto fijo es que tienes un número fijo de bits antes y otro número fijo de bits después del punto decimal (o punto binario). Para una de 32 bits, la división más común probablemente sea par (16 antes, 16 después), pero dependiendo del propósito no hay garantía de eso.

En lo que respecta a la conversión, nuevamente está abierto a alguna variación; por ejemplo, si el número de entrada está fuera del rango del objetivo, es posible que desee hacer cualquier cantidad de cosas diferentes (por ejemplo, en algunos casos envolvente puede tener sentido, pero en otros puede preferirse la saturación).

1

Un tipo de punto fijo es uno que tiene un número fijo de decimales/lugares binarios después de la coma de la base. O más en general, un tipo que puede almacenar múltiplos de 1/N para algunos N. entero positivo

Internamente, los números de coma fija se almacenan como el valor multiplicado por el factor de escala. Por ejemplo, 123.45 con un factor de escala de 100 se almacena como si fuera el entero 12345.

Para convertir el valor interno de un número de punto fijo a coma flotante, simplemente divida por el factor de escala. Para convertir de la otra manera, multiplique por el factor de escala y redondee al entero más cercano.

3

Un ejemplo muy simple para la conversión a punto fijo, se muestra cómo convertir y multiplica PI by2. El resultado se convierte nuevamente en doble para demostrar que la mantisa no se perdió durante el cálculo con números enteros.

Puede expandirlo fácilmente con las tablas de búsqueda sin() y cos() etc. Lo recomendaría si planea usar un punto fijo para buscar una biblioteca de punto fijo de Java.

public class Fix { 

    public static final int FIXED_POINT = 16; 
    public static final int ONE = 1 << FIXED_POINT; 

    public static int mul(int a, int b) { 
     return (int) ((long) a * (long) b >> FIXED_POINT); 
    } 

    public static int toFix(double val) { 
     return (int) (val * ONE); 
    } 

    public static int intVal(int fix) { 
     return fix >> FIXED_POINT; 
    } 

    public static double doubleVal(int fix) { 
     return ((double) fix)/ONE; 
    } 

    public static void main(String[] args) { 
     int f1 = toFix(Math.PI); 
     int f2 = toFix(2); 

     int result = mul(f1, f2); 
     System.out.println("f1:" + f1 + "," + intVal(f1)); 
     System.out.println("f2:" + f2 + "," + intVal(f2)); 
     System.out.println("r:" + result +"," + intVal(result)); 
     System.out.println("double: " + doubleVal(result)); 

    } 
} 

OUTPUT

f1:205887,3 
f2:131072,2 
r:411774,6 
double: 6.283172607421875 
+0

+1 para el método de multiplicar. Sin embargo, hay dos sugerencias para mejorar: ofrecer redondeo al convertir 'doble' al punto fijo; y reemplaza 'toString()' para que se pueda imprimir fácilmente una interpretación adecuada del valor de punto fijo (que luego podrías usar en tu prueba). – MatthewD

16

Un número de punto fijo es una representación de un número real usando un cierto número de bits de un tipo para la parte entera, y los bits restantes del tipo para la parte fraccional. El número de bits que representa cada parte es fijo (de ahí el nombre, punto fijo). Un tipo entero generalmente se usa para almacenar valores de punto fijo.

números de punto fijo se utilizan generalmente en sistemas que no tienen soporte de punto flotante, o necesita más velocidad de la coma flotante puede proporcionar. Los cálculos de punto fijo se pueden realizar utilizando las instrucciones enteras de la CPU.

Un número de coma fija de 32 bits serían almacenados en un tipo de 32 bits como int.

Normalmente cada bit en una (sin firmar en este caso) de tipo entero representaría un valor entero 2^n como sigue:

1 0 1 1 0 0 1 0  = 2^7 + 2^5 + 2^4 + 2^1 = 178 
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0 

Pero si el tipo se utiliza para almacenar un valor de punto fijo, el los bits se interpretan de forma ligeramente diferente:

1 0 1 1 0 0 1 0  = 2^3 + 2^1 + 2^0 + 2^-3 = 11.125 
2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 

el número de punto fijo en el ejemplo anterior se llama un número de 4,4 de punto fijo, ya que hay 4 bits de la parte entera y 4 bits en la parte fraccionaria del número. En un tipo de 32 bits, el valor del punto fijo normalmente estaría en formato 16.16, pero también podría ser 24.8, 28.4 o cualquier otra combinación.

la conversión de un valor de punto flotante a un valor de punto fijo comprende los siguientes pasos:

  1. Multiplicar el flotador por 2^(número de bits fraccionarios para el tipo), por ejemplo. 2^8 para 24.8
  2. Redondee el resultado (simplemente agregue 0.5) si es necesario, y póngalo a un tipo entero (enterándolo) dejando un valor entero.
  3. Asigna este valor al tipo de punto fijo.

Obviamente, puede perder algo de precisión en la parte fraccionaria del número. Si la precisión de la parte fraccionaria es importante, la elección del formato de punto fijo puede reflejar esto, por ej. use 16.16 o 8.24 en lugar de 24.8.

Los valores negativos también pueden manejarse de la misma manera si su número de punto fijo necesita ser firmado.

Si mi Java fuese más fuerte, intentaría algún código, pero generalmente escribo tales cosas en C, por lo que no intentaré una versión de Java. Además, la versión del apilador me parece buena, con la pequeña excepción de que no ofrece la posibilidad de redondeo. Incluso le muestra cómo realizar una multiplicación (¡el cambio es importante!)

+0

+1 por pasar tanto tiempo para un tema tan "héroe olvidado". – stacker

+0

Todo correcto, y sería mejor si proporcionó una solución para que su respuesta pueda ser aceptada. Afortunadamente, tengo eso y lo voy a poner aquí: int number = Float.floatToRawIntBits (floatNumber); – instcode

+0

Estoy aprendiendo este punto fijo también ... En su ejemplo, ¿debería 10.125 * 10^4 = 178? Es igual a 162 en su lugar. –

Cuestiones relacionadas