Представление 128-разрядных чисел в C++

Тот код нормализует разрывы строки, которые могут или не могут быть тем, что Вы действительно хотите сделать.

Вот альтернатива, которая не делает этого, и которая является (IMO) более простой понять, чем код NIO (хотя это все еще использует java.nio.charset.Charset):

public static String readFile(String file, String csName)
            throws IOException {
    Charset cs = Charset.forName(csName);
    return readFile(file, cs);
}

public static String readFile(String file, Charset cs)
            throws IOException {
    // No real need to close the BufferedReader/InputStreamReader
    // as they're only wrapping the stream
    FileInputStream stream = new FileInputStream(file);
    try {
        Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[8192];
        int read;
        while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
            builder.append(buffer, 0, read);
        }
        return builder.toString();
    } finally {
        // Potential issue here: if this throws an IOException,
        // it will mask any others. Normally I'd use a utility
        // method which would log exceptions and swallow them
        stream.close();
    }        
}
55
задан David Coufal 27 July 2009 в 04:44
поделиться

8 ответов

Изучите другие разработанные библиотеки. Многие люди хотели сделать это до вас. : D

Попробуйте bigint C ++

13
ответ дан 7 November 2019 в 07:15
поделиться

Не изобретайте велосипед - я уверен, что другие люди уже решили эту проблему, хотя я не могу придумать какие-либо решения. GMP , безусловно, может решить вашу проблему, хотя это излишне для целых чисел фиксированного размера, а также немного громоздко в использовании (это библиотека C, а не C ++).

2
ответ дан 7 November 2019 в 07:15
поделиться

Вы можете попробовать GMP

2
ответ дан 7 November 2019 в 07:15
поделиться

Вот библиотека, которую я нашел в Google.

http://sourceforge.net/projects/cpp-bigint/

0
ответ дан 7 November 2019 в 07:15
поделиться

Возможно, вам лучше использовать целочисленный класс бесконечной точности, а не последовательность увеличивающегося размера. Некоторые языки (например, Common Lisp и IIRC Python) имеют их изначально. Я не совсем уверен, что доступно для C ++; в последний раз я не видел версии Boost.

0
ответ дан 7 November 2019 в 07:15
поделиться

В Visual Studio C ++ существует тип FLOAT128, который используется для представления 128-битных целых чисел. Он реализован как

#if defined(_M_IA64) && !defined(MIDL_PASS)
__declspec(align(16))
#endif
typedef struct _FLOAT128 {
    __int64 LowPart;
    __int64 HighPart;
} FLOAT128;

, поэтому я не уверен, какие математические операции для него реализованы

-2
ответ дан 7 November 2019 в 07:15
поделиться

РЕДАКТИРОВАТЬ: когда я впервые написал это boost :: multiprecision :: uint128_t еще не было. Сохраняем этот ответ по историческим причинам.


Я создал класс uint128 раньше, вы можете проверить его по адресу: http://www.codef00.com/code/uint128.h .

] Он зависит от ускорения для автоматического предоставления всех вариантов математических операторов, поэтому он должен поддерживать все, что делает собственный тип unsigned int .

Есть некоторые незначительные расширения для встроенных типов, такие как инициализируя его такой строкой:

uint128_t x("12345678901234567890");

Существует вспомогательный макрос, который работает аналогично макросам в C99, и вы можете использовать его следующим образом:

uint128_t x = U128_C(12345678901234567890);
65
ответ дан 7 November 2019 в 07:15
поделиться

Это в некотором роде особый случай, тем более что вы не указали, какие платформы вы ищете, но с GCC вы можете использовать так называемый режим (TI) для получить (синтезировать) 128-битные операции, например:

   typedef unsigned int uint128_t __attribute__((mode(TI)));

   uint64_t x = 0xABCDEF01234568;
   uint64_t y = ~x;

   uint128_t result = ((uint128_t) x * y);

   printf("%016llX * %016llX -> ", x, y);

   uint64_t r1 = (result >> 64);
   uint64_t r2 = result;

   printf("%016llX %016llX\n", r1, r2);

Но это работает только на 64-битных процессорах.

Так или иначе, для решения этой проблемы вы смотрите на арифметику с множественной точностью. mode (TI) заставит компилятор генерировать операции за вас, в противном случае они должны быть написаны явно.

Вы можете использовать общий пакет bigint; известные мне на C ++ включают пакеты теории чисел LiDIA и NTL , а также пакеты bigint, используемые для криптографического кода в Crypto ++ и Botan ]). Плюс конечно есть GnuMP , которая является канонической библиотекой C MPI (и у нее также есть оболочка C ++, хотя в прошлый раз, когда я смотрел на нее, она казалась плохо документированной). Все они разработаны, чтобы быть быстрыми, но также, вероятно, настроены для больших (1000+ бит) чисел, поэтому при 128 битах вы можете иметь дело с большими накладными расходами. (С другой стороны, вы не говорите, имеет это значение или нет). И все они (в отличие от пакета bigint-cpp, который является GPL, либо BSD, либо LGPL) - не уверен, имеет ли это значение - но это может иметь большое значение.

Вы также можете написать собственный тип типа uint128_t; обычно такой класс будет реализовывать те же алгоритмы, что и обычный класс MPI, только жестко запрограммированный, чтобы иметь только 2 или 4 элемента. Если вам интересно, как реализовать такие алгоритмы, хорошая ссылка - Глава 14 Справочника по прикладной криптографии

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

unsigned long long ctrs[2] = { 0 };

void increment() {
   ++ctrs[0];
   if(!ctrs[0]) // overflow
     ++ctrs[1];
}

Что, конечно, будет гораздо проще иметь дело, чем с обычным пакетом MPI или пользовательским классом uint128_t.

20
ответ дан 7 November 2019 в 07:15
поделиться
Другие вопросы по тегам:

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