Обработка чисел в C - PullRequest
       40

Обработка чисел в C

0 голосов
/ 07 июня 2011

Не могу понять, как числа обрабатываются в C. Может ли кто-нибудь указать на хороший учебник.

#include<stdio.h>
main()
{
    printf("%f",16.0/3.0);
}

Этот код дал: 5.333333

Но

#include<stdio.h>
main()
{
    printf("%d",16.0/3.0);
}

Дали какое-то значение мусора: 1431655765

Тогда

#include<stdio.h>
main()
{
    int num;
    num=16.0/3.0;
    printf("%d",num);
}

Дает: 5

Тогда

#include<stdio.h>
main()
{
    float num;
    num=16/3;
    printf("%f",num);
}

Дает: 5.000000

Ответы [ 6 ]

2 голосов
/ 07 июня 2011

printf объявлен как

int printf(const char *format, ...);

первый аргумент (format) - строка, а остальные могут быть чем угодно. Как будут использоваться остальные аргументы в зависимости от спецификаторов формата в format. Если у вас есть:

printf("%d%c", x, y);

x будет рассматриваться как int, y будет рассматриваться как char. Таким образом,

 printf("%f",16.0/3.0);

в порядке, так как вы запрашиваете float double (% f), пас float double (16.0 / 3.0)

printf("%d",16.0/3.0);

вы запрашиваете int (% d), вы передаете float double (double и int имеют различное внутреннее представление), поэтому битовое представление 16.0 / 3.0 (double) соответствует битовому представлению 1431655765 ( целое).

 int num;
 num=16.0/3.0;

компилятор знает, что вы присваиваете int, и конвертирует его для вас. Обратите внимание, что это отличается от предыдущего случая.

2 голосов
/ 07 июня 2011

Хорошо, первая 1 дает правильное значение, как и ожидалось.

Вторая - вы передаете float, когда он обрабатывает его как int (отсюда и "% d", который отображает типы данных int,немного сложно объяснить, почему, и поскольку это только начинается, я бы не стал беспокоиться о том, почему «% d» делает это, когда передал число с плавающей запятой), читая его неправильно, поэтому получая странное значение.(хотя это не мусорное значение).

В-третьих, он делает 16.0 / 3.0 целым числом, присваивая его типу данных int, в результате чего получается 5. Поскольку при создании числа с плавающей точкой int он удаляет десятичные дроби независимо от округления.

В четвертом правая часть (16/3) рассматривается как int, потому что у вас нет нуля .0 в конце.Он оценивает это, затем назначает 5 для числа с плавающей точкойТаким образом, объясняя вывод.

1 голос
/ 07 июня 2011

Вы можете понять числа в C, используя концепцию преобразования типов Implecit.

Во время оценки любого выражения оно придерживается очень строгих правил преобразования типов.и ваш ответ выражения зависит от правил преобразования этого типа.

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

1: Все short и char автоматически преобразуются в int затем

2: если один из операндов равен int , а другой - float , int преобразуется в float , поскольку значение float выше, чем** int **.

, если вы хотите получить больше информации о неявном преобразовании, вы можете обратиться к книге Программирование в ANSI C от E Balagurusamy .

Спасибо.Bye: DeeP

1 голос
/ 07 июня 2011

Это потому, что выбранные вами строки форматирования не соответствуют передаваемым аргументам. Предлагаю посмотреть документацию на принтф. Если у вас есть «% d», он ожидает целочисленное значение, то, как это значение сохраняется, не имеет значения и, вероятно, зависит от машины. Если у вас есть «% f», он ожидает число с плавающей запятой, также, вероятно, зависит от машины. Если вы делаете:

printf( "%f", <<integer>> );

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

16.0/3.0 is a float
int num = 16.0/3.0 is a float converted to an int
16/3 is an int
float num = 16/3 is an int converted to a float

Вы можете искать в Интернете документацию printf. Одна страница на http://linux.die.net/man/3/printf

0 голосов
/ 07 июня 2011
printf("%d",16.0/3.0);

Результат 16.0/3.0 равен 5.333333, который представлен в формате с плавающей запятой одинарной точности следующим образом

0 | 10101010 | +10101010101010101010101

Если вы прочитаете это как 32-битное целое значение, результат будет 1431655765.


num=16.0/3.0;

эквивалентно num = (int)(16.0/3.0). Это преобразует результат значения с плавающей запятой (5.33333) в целое число (5).


printf("%f",num);

совпадает с printf("%f",(float)num);

0 голосов
/ 07 июня 2011

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

...