Лучший способ сделать двоичную арифметику в C?

Pool.map, по сути, передает общую многопроцессорную очередь, из которой извлекаются все рабочие процессы. Каждый работник выполняет бесконечный (или фиксированную итерацию, если установлено maxtasksperchild) цикл, который:

  1. Пытается вытащить задачу из очереди (блокируется, если ни одна не доступна)
  2. Обрабатывается задача
  3. Отправка результата обратно родителю
  4. Перейти к 1

Он не пытается вытащить новую задачу, пока старая не будет завершена, поэтому если один работник получает дешевые задания, он будет выполнять больше; ни один работник не сидит без дела, пока задачи остаются доступными. Так что да, он делает именно то, что вы хотите; это не какой-то циклический перебор или другая статическая схема распределения работы, которая может оставить рабочих без работы, в то время как другие перегружены несколькими ожидающими задачами. Установка chunksize может создать этот эффект, но в этом случае больше о каждом «чанке», считающемся как отдельная задача; куски затем распределяются по требованию, а не по отдельным задачам.

8
задан jmlane 10 November 2017 в 17:25
поделиться

4 ответа

Совет:
Нет очень, это, очевидно, лучше, чем поход через строку символ за один раз и проверка пользователь вводимые только единицы и нули. Следует иметь в виду, что даже при том, что Вы могли записать действительно быструю ассемблерную подпрограмму, если Вы принимаете, все 1 или 0, Вы действительно не хотите делать это. Пользователь мог ввести что-либо, и требуется смочь сказать им, если бы они завинтили или нет.

Это верно, что это кажется, что ум-bogglingly, медленный по сравнению с парой, циклически повторяет его, вероятно, берет для добавления фактических чисел, но действительно имеет значение, если Вы получаете свой ответ за наносекунду или миллисекунду? Люди могут только обнаружить 30 миллисекунд задержки так или иначе.

Наконец, это уже берет намного дольше, чтобы быть введенным от пользователя и записи, выведенной на экран, чем это делает, чтобы проанализировать строку или добавить числа, таким образом, Ваш алгоритм является едва узким местом здесь. Сохраните свою необычную оптимизацию для вещей, которые на самом деле в вычислительном отношении интенсивны :-).

На чем необходимо сфокусироваться, здесь делает задачу менее интенсивной рабочей силой. И, оказывается, что кто-то уже сделал это для Вас.

Решение:
Смотрите на strtol() страница справочника:

long strtol(const char *nptr, char **endptr, int base);

Это позволит Вам преобразовать строку (nptr) в любой основе к длинному. Это проверяет ошибки, также. Демонстрационное использование для преобразования двоичной строки:

#include <stdlib.h>

char buf[MAX_BUF];
get_some_input(buf);

char *err;
long number = strtol(buf, &err, 2);
if (*err) {
    // bad input: try again?
} else {
    // number is now a long converted from a valid binary string.
}

Предоставление основы 2 говорит strtol преобразовать двоичные литералы.

12
ответ дан 5 December 2019 в 10:44
поделиться

Сначала я действительно рекомендую использовать материал как стертол, как рекомендуется tgamblin, лучше использовать вещи, которые lib дает Вам вместо того, чтобы создать колесо много раз.

Но так как Вы изучаете C, которому я действительно немного присваивал версию без стертола, это ни один быстро или безопасно, но я действительно играл немного с побитовой обработкой как пример.

int main()
{
    unsigned int data = 0;
    int i = 0;

    char str[] = "1001";

    char* pos;
    pos = &str[strlen(str)-1];

    while(*pos == '0' || *pos == '1')
    {
        (*pos) -= '0';
        data += (*pos) << i;

        i++;
        pos--;
    }

    printf("data %d\n", data);
    return 0;
}
4
ответ дан 5 December 2019 в 10:44
поделиться

Для получения лучшей производительности необходимо различать доверяемый и недоверяемый вход к функциям.

Например, функция как getBinNum() то, которое признает, что вход от пользователя должен быть проверен на допустимые символы и сжат для удаления продвижения, обнуляет. Во-первых, мы покажем оперативную функцию сжатия общего назначения:

// General purpose compression removes leading zeroes.
void compBinNum (char *num) {
    char *src, *dst;

    // Find first non-'0' and move chars if there are leading '0' chars.
    for (src = dst = num; *src == '0'; src++);
    if (src != dst) {
        while (*src != '\0')
            *dst++ = *src++;
        *dst = '\0';
    }

    // Make zero if we removed the last zero.
    if (*num == '\0')
            strcpy (num, "0");
}

Затем обеспечьте функцию средства проверки, которая возвращает или переданный в значении или ПУСТОЙ УКАЗАТЕЛЬ, если это было недопустимо:

// Check untested number, return NULL if bad.
char *checkBinNum (char *num) {
    char *ptr;

    // Check for valid number.
    for (ptr = num; *ptr == '0'; ptr++)
        if ((*ptr != '1') && (*ptr != '0'))
            return NULL;

    return num;
}

Затем сама функция ввода:

#define MAXBIN 256

// Get number from (untrusted) user, return NULL if bad.
char *getBinNum (char *prompt) {
    char *num, *ptr;

    // Allocate space for the number.
    if ((num = malloc (MAXBIN)) == NULL)
        return NULL;

    // Get the number from the user.
    printf ("%s: ", prompt);
    if (fgets (num, MAXBIN, stdin) == NULL) {
        free (num);
        return NULL;
    }

    // Remove newline if there.
    if (num[strlen (num) - 1] == '\n')
        num[strlen (num) - 1] = '\0';

    // Check for valid number then compress.
    if (checkBinNum (num) == NULL) {
        free (num);
        return NULL;
    }
    compBinNum (num);

    return num;
}

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

char *addBinNum (char *num1, char *num2) {...}
char *mulBinNum (char *num1, char *num2) {...}

Если пользователь принимает решение получить их данные из где-нибудь кроме getBinNum(), Вы могли позволить им звонить checkBinNum() проверить его.

Если бы Вы были действительно параноиками, то Вы могли бы проверить, что каждое число передало в Вашим стандартным программам, и действуйте соответственно (возвратите ПУСТОЙ УКАЗАТЕЛЬ), но это потребовало бы относительно дорогих проверок, которые не необходимы.

1
ответ дан 5 December 2019 в 10:44
поделиться

Разве не было бы легче проанализировать строки в целые числа и затем выполнить Вашу математику на целых числах?

Я предполагаю, что это - школьное присвоение, но я - upvoting Вы, потому что Вы, кажется, даете ему хорошее усилие.

0
ответ дан 5 December 2019 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: