Друзья,изучаю С. Вот такой простой код:
#include <stdlib.h>
double u1;
u1 = rand() / RAND_MAX;По стандарту rand() возвращает int, почему же результат операции (rand() / RAND_MAX) не преобразовывается к double и нужно делать это принудительно:
u1 = (double)rand() / RAND_MAX;
Спасибо!
PS. еще много непонятного в С, поэтому такие глупые вопросы.
>По стандарту rand() возвращает int, почему же результат операции (rand() / RAND_MAX)
>не преобразовывается к double и нужно делать это принудительно:Потому что оба операнда являются целыми числами. Чтобы получить дробное, необходимо, чтобы хотя бы один операнд был вещественным.
P.S. У Кернигана и Ритчи это вроде бы есть. Ищите в окрестностях программки для перевода градусов цельсия в фаренгейты.
>Потому что оба операнда являются целыми числами. Чтобы получить дробное, необходимо, чтобы
>хотя бы один операнд был вещественным.Гм.. но ведь результат мы присваиваем переменной, объявленной как double. По идее правый операнд приводится к типу левого?
>P.S. У Кернигана и Ритчи это вроде бы есть. Ищите в окрестностях
>программки для перевода градусов цельсия в фаренгейты.обязательно поищу.
>>Потому что оба операнда являются целыми числами. Чтобы получить дробное, необходимо, чтобы
>>хотя бы один операнд был вещественным.
>
>Гм.. но ведь результат мы присваиваем переменной, объявленной как double. По идее
>правый операнд приводится к типу левого?Ну да, приводится (в данном случае он "расширится" до double). Только это уже результат будет приводится. А результат-то имеет тип int..
P.S. Но лучше не слушайте меня, а почитайте книжку или даже стандарт!
>>Потому что оба операнда являются целыми числами. Чтобы получить дробное, необходимо, чтобы
>>хотя бы один операнд был вещественным.
>
>Гм.. но ведь результат мы присваиваем переменной, объявленной как double. По идее
>правый операнд приводится к типу левого?
>
>>P.S. У Кернигана и Ритчи это вроде бы есть. Ищите в окрестностях
>>программки для перевода градусов цельсия в фаренгейты.
>
>обязательно поищу.А еще все наверное проходили
double res = 5/2
где res оказывается развным 2, а не 2.5
Так начинающие программисты узнают о приведении типов :)))
>>>Потому что оба операнда являются целыми числами. Чтобы получить дробное, необходимо, чтобы
>>>хотя бы один операнд был вещественным.
>>
>>Гм.. но ведь результат мы присваиваем переменной, объявленной как double. По идее
>>правый операнд приводится к типу левого?
>А еще все наверное проходили
>double res = 5/2
>где res оказывается развным 2, а не 2.5
>Так начинающие программисты узнают о приведении типов :)))с этим уже сталкивался. Но в K&R конкретно не описано, почему так получается, т.е. где в стандарте точно описано поведение и объяснение такого поведения?
Например, везде пишут, что преобразования операндов происходят естественным образом. Выходит и здесь:
double res = 5/2
это должно быть естественно, т.е. результат деления 5 на 2 присваивается переменной с плавающей точкой.
Мда, тяжелее всего объяснять очевидные вещи. Попробуем еще раз. Напомним некоторые факты
1. У опрераций есть приоритеты
2. Все операции выполняются по очереди, с учетом результатов предыдущих, но без учета следующих.
3. Присваивание это тоже операция
Итого получаем:
1. Деление имеет более высокий приоритет чем присваивание, значит выполняется первым
2. "5" это целое число, "2" это целое число, значит будет выполнятся целочисленное деление и результатом его будет "2".
3. Выполняется операция присваивания. "2" целое, а вот res с плавающей точкой, производится преобразование и в res попадет "2.0"
Что остается непонятным?
>3. Выполняется операция присваивания. "2" целое, а вот res с плавающей точкой,
>производится преобразование и в res попадет "2.0"
>Что остается непонятным?неправда, в res как раз попадает 2, проверялось на gcc-4.1.2 Если хотя бы один операнд содержал плавающую точку или применялось бы явное (explicit) преообразование (type casting), тогда и результат преобразовался бы к double.
В этом и была суть вопроса, если бы вы внимательно прочитали.
PS. не стоит так раздражаться на вопросы новичков, все проходят свои "первые шаги в С".
Так у вас еще и с математикой проблемы? Расскажу секрет: 2.0 равно 2 с точки зрения математики. Переменная res у вас имеет тип с плавающей точкой, а значит в ней ВСЕГДА присутствует мантисса и порядок, оно на аппаратном уровне так хранится, а вот выводить на терминал вы ее можете в каком угодно виде.
Вы, разумеется, абсолютно правы... с точки зрения математики. Но зачем же так высокомерно говорить? Ведь форум - это не место, где подскажут, кто какой идиот и насколько кому до кого далеко. А место, где люди собрались, чтобы помочь друг другу. И типа того...P.S. Ну и для того, конечно, чтобы обстебать двоечников-студентов, дабы навсегда отвадить их от написания программ, чтобы они, не приведи господь, не написали какой-нибудь кривой программы управления ядерным реактором, не говоря уже о коллайдерах.
Чего развыступались? Независимо от вступления человек разжевал пошагово процесс, так нет, и этому не рады, а как еще разъяснить, телепатией, чтоли?>Вы, разумеется, абсолютно правы... с точки зрения математики. Но зачем же так
>высокомерно говорить? Ведь форум - это не место, где подскажут, кто
>какой идиот и насколько кому до кого далеко. А место, где
>люди собрались, чтобы помочь друг другу. И типа того...
>
>P.S. Ну и для того, конечно, чтобы обстебать двоечников-студентов, дабы навсегда отвадить
>их от написания программ, чтобы они, не приведи господь, не написали
>какой-нибудь кривой программы управления ядерным реактором, не говоря уже о коллайдерах.
>