it-swarm.com.ru

Зачем писать 1 000 000 000 как 1000 * 1000 * 1000 в C?

В коде, созданном Apple, есть эта строка:

CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )

Есть ли причина выражать 1,000,000,000 как 1000*1000*1000?

Почему бы не 1000^3 в этом отношении?

133
SpaceDog

Одной из причин объявления констант мультипликативным способом является улучшение читабельности, в то время как на производительность во время выполнения это не влияет. Также, чтобы указать, что писатель думал мультипликативным образом о числе. 

Учти это:

double memoryBytes = 1024 * 1024 * 1024;

Это явно лучше чем:

double memoryBytes = 1073741824;

поскольку последний не выглядит, на первый взгляд, третьей степенью 1024. 

Как отметил Амин Негм-Авад, оператор ^ является двоичным XOR. Во многих языках отсутствует встроенный оператор возведения в степень во время компиляции, следовательно, умножение.

193
Piotr Falkowski

Почему не 1000^3?

Результат 1000^3 равен 1003. ^ является оператором bit-XOR.

Даже это не касается самого Q, я добавляю уточнение. x^y делает не всегда оценивает x+y, как это делается в примере спрашивающего. Вы должны xor каждый бит. В случае примера:

1111101000₂ (1000₁₀)
0000000011₂ (3₁₀)
1111101011₂ (1003₁₀)

Но

1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)
72
Amin Negm-Awad

Есть причины нет использовать 1000 * 1000 * 1000.

С 16-разрядным int, 1000 * 1000 переполняется. Таким образом, использование 1000 * 1000 * 1000 уменьшает переносимость. 

С 32-битной int следующие переполнения.

long long Duration = 1000 * 1000 * 1000 * 1000;  // overflow
long long Duration = 1000000000000;  // no overflow, hard to read

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

double Duration = 1000.0 * 1000 * 1000;
long long Duration = 1000LL * 1000 * 1000 * 1000;

Также можно просто использовать нотацию e для значений, которые точно представлены в виде double. Конечно, это приводит к знанию, может ли double точно представлять целое числовое значение - что-то интересное со значениями, превышающими 1e9. (См. DBL_EPSILON и DBL_Dig).

long Duration = 1000000000;
// vs.
long Duration = 1e9;
63
chux

Для удобства чтения. 

Размещение запятых и пробелов между нулями (1 000 000 000 или 1,000,000,000) приведет к синтаксической ошибке, а наличие 1000000000 в коде затрудняет точное определение количества нулей. 

1000*1000*1000 показывает, что это 10 ^ 9, потому что наши глаза могут легче обрабатывать куски. Кроме того, нет затрат времени выполнения, потому что компилятор заменит его константой 1000000000

50
Tamás Zahola

Для удобства чтения. Для сравнения, Java поддерживает _ в числах для улучшения читабельности (впервые предложенный Стивеном Колебурном в качестве ответа на предложение Дерека Фостера: двоичные литералы для Project Coin/JSR 334). Здесь можно написать 1_000_000_000.

Примерно в хронологическом порядке, от самой старой поддержки до самой новой:

Это относительно новая функция для языков, чтобы понять, что они должны поддерживать (и есть Perl). Как и в отличном ответе chux @, 1000*1000... является частичным решением, но открывает программисту ошибки, связанные с переполнением умножения, даже если конечный результат имеет большой тип.

25
djechlin

Может быть проще читать и получить некоторые ассоциации с формой 1,000,000,000

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

Если вы говорите о target-c, то 1000^3 не будет работать, потому что такого синтаксиса для pow нет (это xor). Вместо этого можно использовать функцию pow(). Но в этом случае это не будет оптимальным, это будет вызов функции времени выполнения, а не сгенерированная константой константа.

6
Madars Vi

Для иллюстрации причин рассмотрим следующую тестовую программу:

$ cat comma-expr.c && gcc -o comma-expr comma-expr.c && ./comma-expr
#include <stdio.h>

#define BILLION1 (1,000,000,000)
#define BILLION2 (1000^3)

int main()
{
        printf("%d, %d\n", BILLION1, BILLION2);
}
0, 1003
$
2
Peter A. Schneider

Другим способом достижения аналогичного эффекта в C для десятичных чисел является использование буквенной нотации с плавающей запятой - при условии, что double может представлять желаемое число без потери точности. 

IEEE 754 64-битный double может без проблем представлять любое неотрицательное целое число <= 2 ^ 53. Как правило, long double (80 или 128 бит) может пойти еще дальше. Преобразования будут выполняться во время компиляции, поэтому нет никаких накладных расходов времени выполнения, и вы, скорее всего, получите предупреждения, если произойдет неожиданная потеря точности и у вас будет хороший компилятор.

long lots_of_secs = 1e9;
0
jschultz410