В коде, созданном Apple, есть такая строка:
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
Есть ли причина выражать 1,000,000,000
как 1000*1000*1000
?
Почему не 1000^3
в этом отношении?
В коде, созданном Apple, есть такая строка:
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
Есть ли причина выражать 1,000,000,000
как 1000*1000*1000
?
Почему не 1000^3
в этом отношении?
1_000_000_000
. Однако с постоянными времени это труднее. Писать легче 30 * 60
(30 минут в секундах), чем писать 1800
. На самом деле существуют языки, которые позволят вам писать модули, например meters
, позволяющие защитить себя от неправильных назначений.
^
- это XOR, а не показатель степени или оператор мощности.
Ответы:
Одна из причин объявлять константы мультипликативным способом - это улучшить читаемость, при этом это не повлияет на производительность во время выполнения. Также, чтобы указать, что писатель думал о числе в мультипликативной манере.
Учти это:
double memoryBytes = 1024 * 1024 * 1024;
Это явно лучше, чем:
double memoryBytes = 1073741824;
поскольку последнее, на первый взгляд, не выглядит третьей степенью 1024.
Как упомянул Амин Негм-Авад, ^
оператор является двоичным XOR
. Во многих языках отсутствует встроенный оператор возведения в степень во время компиляции, отсюда и умножение.
x
чтобы получить размер поддиапазона ... и вдруг у вас есть дробная byte, для компенсации которой может потребоваться дополнительная логика.
А почему бы и нет
1000^3
?
Результат 1000^3
- 1003. ^
- это битовый оператор XOR.
Даже если это не касается самого Q, добавлю уточнение. не всегда x^y
дает оценку, как в примере вопрошающего. Вы должны xor каждый бит. В случае примера:x+y
1111101000₂ (1000₁₀)
0000000011₂ (3₁₀)
1111101011₂ (1003₁₀)
Но
1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)
^
Оператор исключающих средств в C / C ++ / Objective-C и т.д. В вычислителях это обычно означает й-к-у власти.
Есть причины не использовать 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;
double
может точно представлять все целые числа до 2 ^ 53 ≈ 9e15.
double
использование binary64, хотя он очень часто используется. Согласно спецификации C, значения до 1e9 или около того являются точными. Это зависит от того, хотите ли вы кодировать согласно спецификации или полагаться на общепринятую практику.
1000
и 1000000000000
являются целочисленными константами . Каждый независимо имеет тип, выбранный из int
, long
или long long
. Компилятор использует первый тип из тех 3, в которые подходит целочисленная константа . 1000 * 1000 * 1000 * 1000
выполняется с помощью int
математики, как каждый 1000
в int
. Продукт переполняется 32-битным int
. 1000000000000
безусловно, можно представить как long long
(или, возможно, уже) - переполнения нет. Тип цели long long Duration
не влияет на эту "правую часть =" детемринации.
int
, long x = 1000 * 1000 * 1000L;
переполнится, пока long x = 1000L * 1000 * 1000;
не будет.
Для удобочитаемости.
Размещение запятых и пробелов между нулями ( 1 000 000 000
или 1,000,000,000
) приведет к синтаксической ошибке, а наличие 1000000000
в коде затрудняет точное определение количества нулей.
1000*1000*1000
делает очевидным, что это 10 ^ 9, потому что нашим глазам легче обрабатывать фрагменты. Кроме того, нет затрат времени выполнения, потому что компилятор заменит его константой 1000000000
.
1,000,000,000
не приведет к синтаксической ошибке, это будет означать что-то другое. НапримерCMTimeMakeWithSeconds( newDurationSeconds, 1,000,000,000 )
1_000_000_000
_
разделителем :)
'
разделитель в C ++ 14, так что вы можете использовать 1'000'000'000
. (Это было выбрано, потому что 1,000,000,000
могло быть неверно истолковано как оператор запятой или 4 различных параметра, и _1_000_000_000
это действительное (но, вероятно, неправильное) имя переменной.)
Для удобочитаемости. Для сравнения, Java поддерживает _
числа для улучшения читаемости (впервые предложено Стивеном Колебурном в ответ на ПРЕДЛОЖЕНИЕ Дерека Фостера: двоичные литералы для Project Coin / JSR 334). Здесь можно было бы написать 1_000_000_000
.
Примерно в хронологическом порядке, от самой старой поддержки до самой новой:
"(1)1111 1111"
(по- видимому, не для десятичных значений, только для цепочек битов, представляющих двоичные, квартальные, восьмеричные или шестнадцатеричные значения )1$000$000
1_000_000_000
1'000'000'000
Это относительно новая функция для языков, позволяющая понять, что они должны поддерживать (а также Perl). Как и в превосходном ответе chux @, 1000*1000...
это частичное решение, но оно открывает программисту возможность ошибок из-за переполнения умножения, даже если конечный результат имеет большой тип.
Возможно, будет проще прочитать и вызвать ассоциации с 1,000,000,000
формой.
С технической точки зрения, думаю, нет никакой разницы между прямым числом и умножением. В любом случае компилятор сгенерирует его как постоянное число в миллиард.
Если говорить о objective-c, то 1000^3
работать не будет, потому что для pow такого синтаксиса нет (это xor). Вместо этого pow()
можно использовать функцию. Но в этом случае это будет неоптимально, это будет вызов функции времени выполнения, а не константа, созданная компилятором.
Чтобы проиллюстрировать причины, рассмотрим следующую программу испытаний:
$ 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
$
Другой способ добиться аналогичного эффекта в C для десятичных чисел - использовать буквальную нотацию с плавающей запятой - при условии, что двойное число может представлять желаемое число без потери точности.
64-битное двойное число IEEE 754 может без проблем представлять любое неотрицательное целое число <= 2 ^ 53. Как правило, long double (80 или 128 бит) может идти даже дальше. Преобразования будут выполняться во время компиляции, поэтому нет накладных расходов во время выполнения, и вы, вероятно, получите предупреждения, если произойдет неожиданная потеря точности и у вас хороший компилятор.
long lots_of_secs = 1e9;