HELP - IEEE - 754 - извлечение, нормализация, NAN и т. Д. - PullRequest
0 голосов
/ 19 января 2010

~ Пожалуйста, прости меня -

  • У меня был предыдущий пост под названием IEEE - 754 - найти признак, экспонента, ГРП, нормализация и т.

Однако я не зарегистрировал свой ник и не могу его отредактировать. (так что пост в основном для меня мертв) Может кто-нибудь удалить его? На мой вопрос тоже нет ответа. Поэтому я публикую это с другим кодом.

  • Мне все еще нужна большая помощь ... поэтому, пожалуйста, не рассматривайте это сообщение как дубликат ...

Я нашел знаковый бит, бит экспоненты и мантиссу ..

Что я проверяю, чтобы найти нормализованный? если exp == 0?

что я проверяю на бесконечность? exp == 0xff и mantiassa == 0? знак имеет какое-либо отношение к этому?

что мне проверить, чтобы найти ноль? exp == 0 и мантисса == 0? знак имеет какое-либо отношение к этому?

Что мне проверить, чтобы найти NAN? Может кто-нибудь объяснить, пожалуйста, так просто, как вы можете, так как я только начинающий! Должен ли я применить еще маски?

  • Есть ли порядок, в котором я должен выполнить то, что хочу?

Это то, что у меня есть.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int HexNumber;

    printf("IEEE- 754 \n");
    int a = 0x12345678;
    unsigned char *c = (unsigned char*)(&a);

    if (*c == 0x78) {
      printf("\nlittle-endian\n");
    } else {
      printf("\nbig-endian\n");
    }

    printf("\n>");
    scanf("%x", &HexNumber);
    printf("\n%#x",HexNumber);

    bool negative = !!(HexNumber & 0x80000000);
    int exponent = (HexNumber & 0x7f800000) >> 23;
    int mantissa = (HexNumber & 0x007FFFFF);

    printf("\nsignBit %d,", negative);
    printf("expbits %d,", exponent);
    printf("fractbits %#x,", mantissa);

    return 0;
}

... и это мой вывод - вот чего я хочу:

IEEE - 754 

little-endian

>C0000000

0xc0000000
signBit 1,expbits 128,fractbits 0,

Ответы [ 3 ]

2 голосов
/ 19 января 2010

Почему бы не проверить это самостоятельно?

#include <stdio.h>

void extract (float x) {
    union {
        float value;
        struct {
            unsigned int frac : 23;
            unsigned int exp  : 8;
            unsigned int sign : 1;
        } fields;
    } conv;
    conv.value = x;
    printf ("Value = %.3g,\tSign = %x,\tExp = %x,\tFrac = %x\n", x, conv.fields.sign, conv.fields.exp, conv.fields.frac);
}

int main() {
    extract (1.0f);     // normal number
    extract (1.0f/3.0f);    // normal number
    extract (0.0f);     // 0
    extract (-0.0f);    // -0
    extract (1.0f / 0.0f);  // inf
    extract (-1.0f / 0.0f); // -inf
    extract (0.0f / 0.0f);  // nan
    extract (1.e-40f);  // denormal
    extract (-1.e-42f); // denormal
    return 0;
}

Результат:

Value = 1,  Sign = 0,   Exp = 7f,   Frac = 0
Value = 0.333,  Sign = 0,   Exp = 7d,   Frac = 2aaaab
Value = 0,  Sign = 0,   Exp = 0,    Frac = 0
Value = -0, Sign = 1,   Exp = 0,    Frac = 0
Value = inf,    Sign = 0,   Exp = ff,   Frac = 0
Value = -inf,   Sign = 1,   Exp = ff,   Frac = 0
Value = nan,    Sign = 0,   Exp = ff,   Frac = 400000
Value = 1e-40,  Sign = 0,   Exp = 0,    Frac = 116c2
Value = -1e-40, Sign = 1,   Exp = 0,    Frac = 116c2

Наблюдение:

  • Если exp = 0xff, это либо± инф или нан.
    • Если frac = 0, это inf (+ или -).
    • Если frac≠ 0, это nan (знаковый бит не имеет значения).
  • Если exp = 0, это либо ноль, либо ненормальный.
    • Если frac = 0, то это ноль (+ или -).
    • Если frac ≠ 0, это ненормально (+ или-).

Если вы используете C, то уже есть isnan, isinf / isfinite, isnormal и signbitв <math.h> для этих тестов.

2 голосов
/ 19 января 2010

В C99 вы можете использовать макросы fpclassify() и signbit() из math.h (черновик C99, F.3):

Макрос signbit и макрос fpclassify в <math.h>, используемые вместе с макросами классификации чисел (FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO), обеспечивают средство функции класса, рекомендованное в Приложении к МЭК 60559 (за исключением того, что макросы классификации, определенные в 7.12.3, не отличают сигнализацию от тихих NaN).

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

int my_fpclassify(uint32_t x)
{
    x &= 0x7fffffff;
    if (x == 0)
        /* zero */
    else if (x < 0x800000)
        /* subnormal */
    else if (x > 0x7f800000)
        /* nan */
    else if (x == 0x7f800000)
        /* inf */
    else
        /* normal */
}

int my_signbit(uint32_t x)
{
    return x & 0x80000000;
}
0 голосов
/ 19 января 2010

Если вы используете c99, попробуйте функцию fpclassify, которая будет возвращать перечисление с указанием значения NAN, Infinity и т. Д., И frexp, который разделит значение для вас.

ЕслиВы хотите свернуть свое собственное, помните, что и бесконечности и нули подписаны.NaN определяются определенным битовым шаблоном в показателе степени, который, я считаю, мантисса дает дополнительную информацию нестандартным способом.

Из чтения чернового стандарта :

  • Если показатель степени равен нулю, а мантисса отлична от нуля, значение является ненормальным

  • Если показатель степени равен нулю и мантисса равна нулю, значение равно (+/-) нулю

  • Если показатель степени максимален, а мантисса равна нулю, значение равно (+/-) бесконечности

  • Если показатель степени максимален иМантисса отлична от нуля, значение равно NAN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...