Pull to refresh
39
0
Евгений Желтоножский @Randl

Программист

Send message

Призрачная галактика на 99.99% состоит из тёмной материи и почти не содержит звёзд

Reading time 2 min
Views 26K

image
Credit: Pieter van Dokkum, Roberto Abraham, Gemini, Sloan Digital Sky Survey


У Млечного Пути нашелся тёмный близнец. Тусклая массивная галактика Dragonfly 44(Стрекоза 44 — прим. переводчика) состоит из тёмной материи на рекордных 99.99% и может помочь переписать наши теории об образования галактик. Dragonfly 44 похожа на Млечный Путь по массе, но отличается по количеству звезд и структуре.


– Если взять Млечный Путь и из каждых 100 звёзд оставить одну, получится примерно то же самое – говорит Питер ван Доккум из Йельского университета. – Придется также взять эти оставшиеся звёзды и перемешать в блендере.
Эта галактика — не спиральная, как Млечный путь, но и не плоский диск.

Читать дальше →
Total votes 22: ↑20 and ↓2 +18
Comments 61

Каламбуры типизации функций в C

Reading time 8 min
Views 23K

У C репутация негибкого языка. Но вы знаете, что вы можете изменить порядок аргументов функции в C, если он вам не нравится?


#include <math.h>
#include <stdio.h>

double  DoubleToTheInt(double base, int power) {
    return pow(base, power);
}

int main() {
    // приводим к указателю на функуцию с обратным порядком аргументов
    double (*IntPowerOfDouble)(int, double) =
        (double (*)(int, double))&DoubleToTheInt;

    printf("(0.99)^100: %lf \n", DoubleToTheInt(0.99, 100));
    printf("(0.99)^100: %lf \n", IntPowerOfDouble(100, 0.99));
}

Этот код на самом деле никогда не определяет функцию IntPowerOfDouble — потому что функции IntPowerOfDouble не существует. Это переменная, указывающая на DoubleToTheInt, но с типом, который говорит, что ему хочется, чтобы аргумент типа int шел перед аргументом типа double.


Вы могли бы ожидать, что IntPowerOfDouble примет аргументы в том же порядке, что и DoubleToTheInt, но приведет аргументы к другим типам, или что-то типа того. Но это не то, что происходит.


Попробуйте — вы увидите одинаковый результат в обоих строчках.


emiller@gibbon ~> clang something.c 
emiller@gibbon ~> ./a.out 
(0.99)^100: 0.366032 
(0.99)^100: 0.366032 
Читать дальше →
Total votes 78: ↑74 and ↓4 +70
Comments 38

Const и оптимизации в C

Reading time 3 min
Views 19K

Сегодня на /r/C_Programming задали вопрос о влиянии const в C на оптимизацию. Я много раз слышал варианты этого вопроса в течении последних двадцати лет. Лично я обвиняю во всём именование const.

Читать дальше →
Total votes 44: ↑43 and ↓1 +42
Comments 28

C/C++: как измерять процессорное время

Reading time 10 min
Views 79K

image
КДПВ


От переводчика:
Большинство моих знакомых для измерения времени в разного вида бенчмарках в С++ используют chrono или, в особо запущенных случаях, ctime. Но для бенчмаркинга гораздо полезнее замерять процессорное время. Недавно я наткнулся на статью о кроссплатформенном замере процессорного времени и решил поделиться ею тут, возможно несколько увеличив качество местных бенчмарков.


P.S. Когда в статье написано "сегодня" или "сейчас", имеется ввиду "на момент выхода статьи", то есть, если я не ошибаюсь, март 2012. Ни я, ни автор не гарантируем, что это до сих пор так.
P.P.S. На момент публикации оригинал недоступен, но хранится в кэше Яндекса


Функции API, позволяющие получить процессорное время, использованное процессом, отличаются в разных операционных системах: Windows, Linux, OSX, BSD, Solaris, а также прочих UNIX-подобных ОС. Эта статья предоставляет кросс-платформенную функцию, получающую процессорное время процесса и объясняет, какие функции поддерживает каждая ОС.

Читать дальше →
Total votes 32: ↑29 and ↓3 +26
Comments 69

Как компьютер играет в шахматы?

Reading time 14 min
Views 95K

Хикару Накамура, недавно бросивший вызов компьютеру

Компьютер уже давно обыграл человека в шахматы, сейчас сильнейшие шахматисты не способны выиграть даже у старенького ноутбука. Теперь шахматные движки используются для анализа партий, поиска новых вариантов и игры по переписке.

Если вам интересно, как же устроены шахматные движки — добро пожаловать под кат.
Читать дальше →
Total votes 40: ↑39 and ↓1 +38
Comments 56

Внешняя сортировка с O(1) дополнительной памяти

Reading time 9 min
Views 36K
Прочитав эту статью, я вспомнил, как писал внешнюю сортировку, которая использовала O(1) внешней памяти. Функция получала бинарый файл и максимальный размер памяти, которую она могла выделить под массив:

void ext_sort(const std::string filename, const size_t memory)

Я использовал алгоритм из Effective Performance of External Sorting with No Additional Disk Space:

  1. Разделим файл на блоки, которые помещаются в доступную память. Обозначим эти блоки Block_1, Block_2, …, Block_(S-1), Block_S. Установим P = 1.
  2. Читаем Block_P в память.
  3. Отсортируем данные в памяти и запишем назад в Block_P. Установим P = P + 1, и если P ≤ S, то читаем Block_P в память и повторяем этот шаг. Другими словами, отсортируем каждый блок файла.
  4. Разделим каждый блок на меньшие блоки B_1 и B_2. Каждый из таких блоков занимает половину доступной памяти.
  5. Читаем блок B_1 блока Block_1 в первую половину доступной памяти. Установим Q = 2.
  6. Читаем блок B_1 блока Block_Q во вторую половину доступной памяти.
  7. Объеденим массивы в памяти с помощью in-place слияния, запишем вторую половину памяти в блок B_1 блока Block_Q и установим Q = Q + 1, если Q ≤ S, читаем блок B_1 блока Block_Q во вторую половину доступной памяти и повторяем этот шаг.
  8. Записываем первую половину доступной памяти в блок B_1 блока Block_1. Так как мы всегда оставляли в памяти меньшую половину элементов и провели слияние со всеми блоками, то в этой части памяти хранятся M минимальных элементы всего файла.
  9. Читаем блок B_2 блока Block_S во вторую половину доступной памяти. Установим Q = S −1.
  10. Читаем блок B_2 блока Block_Q в первую половину доступной памяти.
  11. Объеденим массивы в памяти с помощью in-place слияния, запишем первую половину доступной памяти в блок B_2 блока Block_Q и установим Q = Q −1. Если Q ≥ 1 читаем блок B_2 блока Block_Q в первую половину доступной памяти и повторяем этот шаг.
  12. Записываем вторую половину доступной памяти в блок B_2 блока Block_S. Аналогично шагу 8, тут хранятся максимальные элементы всего файла.
  13. Начиная от блока B_2 блока Block_1 и до блока B_1 блока Block_S, определим новые блоки в файле и снова пронумеруем их Block_1 to Block_S. Разделим каждый блок на блоки B_1 и B_2. Установим P = 1.
  14. Читаем B_1 и B_2 блока Block_P в память. Объеденим массивы в памяти. запишем отсортированный массив назад в Block_P и установим P = P +1. Если P ≤ S, повторяем этот шаг.
  15. Если S > 1, возвращаемся к шагу 5. Каждый раз мы выделяем M минимальных и максимальных элементов, записываем их в начало и конец файла соответственно, а потом делаем то же самое с оставшимися элементами, пока не дойдем до середины файла.

Преимущество такого алгоритма, кроме отсутствия буфера на диске, это то, что с диска мы читаем данные относительно большими порциями, что ускоряет алгоритм.

Реализуем алгоритм на C++.
Читать дальше →
Total votes 28: ↑23 and ↓5 +18
Comments 9

Information

Rating
Does not participate
Location
Хайфа, Хацафон, Израиль
Works in
Date of birth
Registered
Activity