преобразование плавающей точки к 32-разрядной фиксированной точке в Java

Я должен преобразовать плавающую точку в 32-разрядную фиксированную точку в Java.

Не способный понять, что такое 32-разрядная фиксированная точка?

Какое-либо тело может помочь с алгоритмом?

9
задан Abhijith V R 4 August 2010 в 04:57
поделиться

4 ответа

Число с фиксированной точкой - это представление действительного числа с использованием определенного количества битов типа для целой части и оставшихся битов типа для дробной части. Количество битов, представляющих каждую часть, фиксировано (отсюда и название - с фиксированной точкой). Целочисленный тип обычно используется для хранения значений с фиксированной точкой.

Числа с фиксированной запятой обычно используются в системах, которые не имеют поддержки с плавающей запятой или требуют большей скорости, чем может обеспечить плавающая запятая. Вычисления с фиксированной точкой могут выполняться с использованием целочисленных инструкций ЦП.

32-битное число с фиксированной запятой будет храниться в 32-битном типе, таком как int .

Обычно каждый бит в целочисленном типе (в данном случае без знака) представляет собой целое значение 2 ^ n следующим образом:

 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

Но если тип используется для хранения значения с фиксированной точкой, биты интерпретируются несколько иначе :

 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

Число с фиксированной запятой в приведенном выше примере называется числом с фиксированной запятой 4.4, поскольку имеется 4 бита в целой части и 4 бита в дробной части числа. В 32-битном типе значение с фиксированной запятой обычно будет в формате 16,16, но также может быть 24,8, 28,4 или любой другой комбинацией.

Преобразование значения с плавающей запятой в значение с фиксированной запятой включает следующие шаги:

  1. Умножение числа с плавающей запятой на 2 ^ (количество дробных битов для типа), например. 2 ^ 8 для 24,8
  2. Округлите результат (просто добавьте 0,5), если необходимо, и уменьшите его (или приведите к целочисленному типу), оставив целочисленное значение.
  3. Назначьте это значение типу с фиксированной точкой.

Очевидно, вы можете потерять некоторую точность дробной части числа. Если точность дробной части важна, выбор формата с фиксированной точкой может отразить это - например. используйте 16,16 или 8,24 вместо 24,8.

Отрицательные значения также могут обрабатываться таким же образом, если ваш номер с фиксированной точкой должен быть подписан.

Если бы моя Java была сильнее, я бы попробовал какой-нибудь код, но я обычно пишу такие вещи на C, поэтому я не буду пытаться создать версию Java. Кроме того, мне нравится версия stacker , за небольшим исключением, что в ней нет возможности округления. Он даже показывает вам, как выполнять умножение (сдвиг важен!)

24
ответ дан 4 December 2019 в 07:04
поделиться

Очень простой пример преобразования в фиксированную точку, он показывает, как преобразовать и умножить PI на2. Результат преобразуется обратно в double, чтобы продемонстрировать, что мантисса не была потеряна во время вычисления с целыми числами.

Вы можете легко расширить это с помощью таблиц поиска sin () и cos () и т. Д. Я бы порекомендовал, если вы планируете использовать фиксированную точку, для поиска библиотеки фиксированной точки 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 ));

    }
}

ВЫХОД

f1:205887,3
f2:131072,2
r:411774,6
double: 6.283172607421875
5
ответ дан 4 December 2019 в 07:04
поделиться

Определение 32-битной фиксированной точки может варьироваться. Общая идея фиксированной точки состоит в том, что у вас есть фиксированное количество бит до и другое фиксированное количество бит после десятичной точки (или двоичной точки). Для 32-битного наиболее распространенного разделения, вероятно, будет четное (16 до, 16 после), но в зависимости от цели нет гарантии этого.

Что касается преобразования, опять же, он открыт для некоторых вариаций - например, если входной номер выходит за пределы целевого диапазона, вы можете захотеть выполнить любое количество разных действий (например, в некоторых случаях может иметь смысл, но в других может быть предпочтительнее насыщенность).

1
ответ дан 4 December 2019 в 07:04
поделиться

Тип с фиксированной точкой - это тип, который имеет фиксированное количество десятичных/двоичных разрядов после точки радикса. Или, в более общем случае, тип, который может хранить числа, кратные 1/N для некоторого положительного целого числа N.

Внутренне числа с фиксированной точкой хранятся как значение, умноженное на масштабный коэффициент. Например, 123.45 с масштабным коэффициентом 100 хранится как целое число 12345.

Чтобы преобразовать внутреннее значение числа с фиксированной точкой в число с плавающей точкой, просто разделите его на масштабный коэффициент. Чтобы преобразовать в другую сторону, умножьте на масштабный коэффициент и округлите до ближайшего целого числа.

2
ответ дан 4 December 2019 в 07:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: