В коде, созданном Apple, есть такая строка:
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
Есть ли причина выражать 1,000,000,000
как 1000*1000*1000
?
Почему не 1000^3
в этом отношении?
objective-c
c
integer
literals
Утка
источник
источник
1_000_000_000
. Однако с постоянными времени это труднее. Писать легче30 * 60
(30 минут в секундах), чем писать1800
. На самом деле существуют языки, которые позволят вам писать модули, напримерmeters
, позволяющие защитить себя от неправильных назначений.^
- это XOR, а не показатель степени или оператор мощности.Ответы:
Одна из причин объявлять константы мультипликативным способом - это улучшить читаемость, при этом это не повлияет на производительность во время выполнения. Также, чтобы указать, что писатель думал о числе в мультипликативной манере.
Учти это:
double memoryBytes = 1024 * 1024 * 1024;
Это явно лучше, чем:
double memoryBytes = 1073741824;
поскольку последнее, на первый взгляд, не выглядит третьей степенью 1024.
Как упомянул Амин Негм-Авад,
^
оператор является двоичнымXOR
. Во многих языках отсутствует встроенный оператор возведения в степень во время компиляции, отсюда и умножение.источник
x
чтобы получить размер поддиапазона ... и вдруг у вас есть дробная byte, для компенсации которой может потребоваться дополнительная логика.Результат
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;
источник