2013-02-16 3 views
0

В следующем примере, как бы напечатать значение в u? Я продолжаю печатать адрес.Печать значения из указателя в C

int example (float f) 
{ 
    unsigned int u = *(unsigned int*)&f; 
    printf("The value in u is: %u\n", u); 
} 

EDIT

У меня есть что-то вроде этого:

int example (float f) 
{ 
    unsigned int u = *(unsigned int*)&f; 

    if((u&u) && u != MASK) { 

    printf("The value in u is: %u\n", u); 

    printf("The address in u is: %u" , u); 
    } 
} 

int main() 
{ 
    example(3); 
    return(EXIT_SUCCESS); 
} 

Проблема, что у меня есть, когда я пытаюсь проверить и распечатать значение «и». Кажется, я не могу распечатать его.

+0

Что вы хотите распечатать? – ouah

+0

Если бы я положил значение в u, например: u = u &mask; Если бы я хотел увидеть фактическое значение в u, как бы напечатать его, а не получить адрес? – Mus

+0

Что вы пытаетесь достичь с помощью 'unsigned int u = * (unsigned int *) & f;'? Преобразование 'float' в' unsigned int'? – ouah

ответ

1

Это расширение вашего кода, которое компилируется и работает под управлением GCC 4.7.1 на Mac OS X 10.7.5.

#include <stdio.h> 
#include <inttypes.h> 

static void example(float f) 
{ 
    unsigned int u = *(unsigned int*)&f; 
    printf("%13.6e: %10u = 0x%08X (address 0x%08" PRIXPTR ")\n", 
      f, u, u, (uintptr_t)&f); 
} 

int main(void) 
{ 
    example(+3.14159F); 
    example(+0.0); 
    example(-0.0); 
    example(+3.456789e24); 
    example(3.456789e-24); 
    example(-3.456789e24); 
    example(-3.456789e-24); 
    return(0); 
} 

Выход:

3.141590e+00: 1078530000 = 0x40490FD0 (address 0x7FFF5FD3754C) 
0.000000e+00:   0 = 0x00000000 (address 0x7FFF5FD3754C) 
-0.000000e+00: 2147483648 = 0x80000000 (address 0x7FFF5FD3754C) 
3.456789e+24: 1748435002 = 0x6837003A (address 0x7FFF5FD3754C) 
3.456789e-24: 411417185 = 0x1885BA61 (address 0x7FFF5FD3754C) 
-3.456789e+24: 3895918650 = 0xE837003A (address 0x7FFF5FD3754C) 
-3.456789e-24: 2558900833 = 0x9885BA61 (address 0x7FFF5FD3754C) 

Как вы можете видеть, я использую 64-битную машину. Вы можете видеть в шестнадцатеричном виде, что бит знака находится в самом значительном байте; менее очевидно, что показатель находится в следующих 8 бит, а мантисса - в остальных 23 бит.

Ваш код очень близок к тому, что я демонстрирую - как только опечатки были исправлены. Ваш код с использованием MASK таинственный, так как вы не показываете, что такое MASK. Тем не менее, он должен печатать информацию практически для любого значения float, кроме положительного нуля (потому что тогда u&u оценивает значение false) или одно определенное значение с плавающей точкой, которое имеет битовый шаблон, который соответствует MASK.

Для моего кода, компилятор предупреждает:

$ gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \ 
     -Wold-style-definition x.c -o x 
x.c: In function ‘example’: 
x.c:6:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 
$ 

Вот другое расширение, и более выходных данных:

#include <stdio.h> 
#include <inttypes.h> 

static void example(float f) 
{ 
    unsigned int u = *(unsigned int*)&f; 
    unsigned int s = u >> 31; 
    unsigned int e = (u >> 23) & 0xFF; 
    unsigned int m = (u >> 16) & 0x7F; 
    printf("%13.6e: %10u = 0x%08X (s=%u, e=x%02X, m=0x%02X) (0x%08" PRIXPTR ")\n", 
      f, u, u, s, e, m, (uintptr_t)&f); 
} 

int main(void) 
{ 
    example(+3.14159F); 
    example(+0.0); 
    example(-0.0); 
    example(+1.0); 
    example(-1.0); 
    example(+2.0); 
    example(-2.0); 
    example(+3.0); 
    example(-3.0); 
    example(+4.0); 
    example(-4.0); 
    example(+5.0); 
    example(-5.0); 
    example(+3.456789e24); 
    example(3.456789e-24); 
    example(-3.456789e24); 
    example(-3.456789e-24); 
    return(0); 
} 

Выход:

3.141590e+00: 1078530000 = 0x40490FD0 (s=0, e=x80, m=0x49) (0x7FFF6112754C) 
0.000000e+00:   0 = 0x00000000 (s=0, e=x00, m=0x00) (0x7FFF6112754C) 
-0.000000e+00: 2147483648 = 0x80000000 (s=1, e=x00, m=0x00) (0x7FFF6112754C) 
1.000000e+00: 1065353216 = 0x3F800000 (s=0, e=x7F, m=0x00) (0x7FFF6112754C) 
-1.000000e+00: 3212836864 = 0xBF800000 (s=1, e=x7F, m=0x00) (0x7FFF6112754C) 
2.000000e+00: 1073741824 = 0x40000000 (s=0, e=x80, m=0x00) (0x7FFF6112754C) 
-2.000000e+00: 3221225472 = 0xC0000000 (s=1, e=x80, m=0x00) (0x7FFF6112754C) 
3.000000e+00: 1077936128 = 0x40400000 (s=0, e=x80, m=0x40) (0x7FFF6112754C) 
-3.000000e+00: 3225419776 = 0xC0400000 (s=1, e=x80, m=0x40) (0x7FFF6112754C) 
4.000000e+00: 1082130432 = 0x40800000 (s=0, e=x81, m=0x00) (0x7FFF6112754C) 
-4.000000e+00: 3229614080 = 0xC0800000 (s=1, e=x81, m=0x00) (0x7FFF6112754C) 
5.000000e+00: 1084227584 = 0x40A00000 (s=0, e=x81, m=0x20) (0x7FFF6112754C) 
-5.000000e+00: 3231711232 = 0xC0A00000 (s=1, e=x81, m=0x20) (0x7FFF6112754C) 
3.456789e+24: 1748435002 = 0x6837003A (s=0, e=xD0, m=0x37) (0x7FFF6112754C) 
3.456789e-24: 411417185 = 0x1885BA61 (s=0, e=x31, m=0x05) (0x7FFF6112754C) 
-3.456789e+24: 3895918650 = 0xE837003A (s=1, e=xD0, m=0x37) (0x7FFF6112754C) 
-3.456789e-24: 2558900833 = 0x9885BA61 (s=1, e=x31, m=0x05) (0x7FFF6112754C) 

Это начинает анализировать IEEE 754 single-pricision floating point format в некоторых деталях. На ссылаемой странице в Википедии приведена дополнительная информация о том, почему значения, которые я использовал для создания s, e, m, имеют значение (отмечая, что я работаю на машине Intel и, следовательно, это малорисковые данные).

За исключением значений «постепенного понижения», нулей, бесконечности и NaN, первый бит «настоящей» мантиссы всегда равен 1, поэтому формат на самом деле не сохраняет это. Вы можете видеть это из значений для 1, 2, 4 - контраста с 3 и 5 (каждый из которых имеет только один бит, установленный в мантиссе, хотя двоичное представление 3 и 5 содержит два набора бит).

+0

Ах, отлично, это проясняет, спасибо! – Mus

Смежные вопросы