Почему C принимает целочисленный тип в расчете для double? - PullRequest
1 голос
/ 28 июля 2011

Я пытался построить функцию в графике GNU, и мой график не совпадал с тем, что представлен в статье.Прочитав, что GNU интерпретирует функции как C, я попытался кодировать функцию в C. Та же проблема.

В конце концов я понял, что проблему можно продемонстрировать с помощью этого лакомого кусочка:

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

int main()
{
double p = 1.0;
double pMinusOneHalf1 = p - (1.0/2.0);
double pMinusOneHalf2 = p - (1/2);

printf("\nFirst = %lf \n Second = %lf\n\n", pMinusOneHalf1, pMinusOneHalf2);

return 0;
}

, который дает вывод

First = 0.500000 
Second = 1.000000

Просто интересно, есть ли у кого-нибудь объяснение, почемуC принял бы «1» и «2» как INT внутри выражения для DOUBLE.

Кажется, что людям очень легко попасться.Опция gcc -Wall даже не комментирует это.

Ответы [ 5 ]

9 голосов
/ 28 июля 2011

/ не особо заботится о том, чтобы его результат вычитался из double.

Все, что он знает, это то, что ему дано два целых числа, поэтому он возвращает вам целое число.

1 голос
/ 28 июля 2011

Почему они этого не делают?

Они предполагают, что пользователь, который программирует INT / INT, будет знать, что он / она делает, а не будет угадывать его / его.Что если вы хотите целочисленное деление?Собираетесь ли вы заставить пользователя использовать дополнительную запись?Мне кажется, что выражения можно оценивать локально в соответствии с определенным поведением, а не пытаться угадать, чего хочет пользователь.В противном случае, gcc может просто угадать, где вы хотите вставить точку с запятой, и сделать это для вас.

0 голосов
/ 28 июля 2011

Целочисленные константы 1 и 2 имеют тип int (как и любая десятичная целочисленная константа, значение которой не превышает INT_MAX).

В большинстве случаев тип выражения C полностью определяется самим выражением, а не контекстом, в котором оно появляется. (1/2) - выражение типа int со значением 0; тот факт, что он вычитается из выражения типа double, не меняет этого.

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

0 голосов
/ 28 июля 2011

Ваше выражение оценивается в том порядке, в котором вы говорите.В этом случае деление имеет более высокий приоритет, чем вычитание (круглые скобки вокруг деления или нет).Таким образом, первая часть оцениваемого уравнения - 1/2.Как вы знаете, 1/2 равно 0 в целочисленной арифметике.Тогда выражение становится (1,0-0), которое преобразует результат в удвоенный, но результат 1.0-0 равен 1.0.

0 голосов
/ 28 июля 2011

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

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