2013-05-10 2 views
8

Скажем, у меня есть этот номер :Как получить детали с несколькими точками преломления?

// bmp = boost::multiprecision 
bmp::cpp_dec_float n("123456789.1234567891011121314"); 

его внутренними данными являются:

[0] 1   unsigned int 
[1] 23456789 unsigned int 
[2] 12345678 unsigned int 
[3] 91011121 unsigned int 
[4] 31400000 unsigned int 
... 0 
[15] 0   unsigned int 

это именно то, что я хочу получить; к сожалению, я не нашел способ получить обе части моего номера как bmp::int128_t --for instance--, или базовые данные моего номера.

То есть, мне нравится что-то подобное существует:

bmp::int128_t integerPart; 
bmp::int128_t floatPart; 
n.getParts(integerPart, floatPart); 

или

auto&& data = n.data(); // which is actually private when using `cpp_dec_float`. 

Во всяком случае, кто-то знал, как сделать то, что я пытаюсь достичь?

Для записи мне нужно это, чтобы выразить большое десятичное число как десятичное число C# ради интероперабельности.

ответ

-1

Я подозреваю, что вы можете использовать eval_frexp, чтобы получить значения, которые вы ищете, хотя вам все равно придется проверять, что они вписываются в тип C# Decimal. См. Руководство по основным требованиям Boost.Multiprecision: здесь: http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/boost_multiprecision/ref/backendconc.html

Вы всегда можете просто провести математику и проверку диапазона; если вы не переносите слишком много номеров, это может быть достаточно быстро.

Сказав все это, вы можете шалить и сделать что-то вроде:

#define private public 
#define protected public 
#include <boost/multiprecision/cpp_dec_float.hpp> 
#undef private 
#undef protected 

Но если он ломает в будущих версиях, вы получите держать обе части.


Эй, спасибо за нижний ни одного комментария. Это действительно полезно.

Чтобы уточнить мои комментарии выше:

Использование eval_frexp: после дальнейших исследований, кажется, что eval_frexp(b, cb, pi) все еще только предлагают полномочия 2, а не силы 10, как представляется, требует для Decimal типа. Поэтому я подозреваю, что вам нужно сделать арифметику в длинной форме, если вы хотите использовать только открытый интерфейс.

Злоупотребление private членов: авторы и сопровождающие классы Boost.Multiprecision разработали их в соответствии с определенными рекомендациями; они, по-видимому, оценивали будущую защиту как более важную, чем обеспечение доступа к внутренней структуре:

Шаблон класса cpp_dec_float выполняет все требования для типа Backend. Его члены и функции, не являющиеся членами, преднамеренно не документированы: они рассматриваются как детали реализации, которые могут быть изменены. (http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/boost_multiprecision/ref/cpp_dec_ref.html)

Мое предложение, которое было четко помечается как «непослушные» и с предупреждением, что он, скорее всего, перерыв в будущих версиях было ввести потребности конструктивные О.П. впереди тех автора B.MP.

Самый чистый метод может заключаться в том, чтобы предложить изменение класса cpp_dec_float, где показана внутренняя структура; учитывая убедительный пример использования и анализ того, насколько код исторически или исторически не изменился, его можно даже принять.

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

+0

Это не я , но ключевые слова '# define' являются неопределенным поведением и (почти?) никогда не являются твердым решением проблем. –

+0

О, никаких аргументов нет. Я попытался сформулировать исходный ответ (и мой snarky комментарий о downvote), чтобы быть ясным, что это не то, что является хорошей идеей для использования в производстве. Если OP действительно нуждается в этой возможности в долгосрочной перспективе, то, если они не могут убедить сторонников B.MP, они должны просто разветвить ее и сосать ее в свою кодовую базу - это позволяет BPL. Я просто пытался предложить решение «это 11 вечера, и вам нужно это завтра». Может быть, это стоит нисходящего, не знаю. – AnthonyFoiani

+0

Забавный анекдот: я попытался создать memo-генератор «#define private public, NO REGRETS» для внутреннего генератора meme в моей текущей компании ... только для перенаправления на * существующий * пример. Поэтому я думаю, что я не единственная сумасшедшая душа с этой идеей. :) – AnthonyFoiani

0

Я не знаю, если это вы ищете, попробуйте ...

cpp_dec_float_100 myreal(100); 
cpp_dec_float_100 int_part = myreal.backend().extract_integer_part(); 

Тип еще cpp_dec_float_100, но содержит только целую часть. Надеюсь, это поможет.

1

Из документации по ускорению задний конец намеренно непрозрачен, так как он может меняться в любое время без предупреждения. (Class template cpp_dec_float fulfils all of the requirements for a Backend type. Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject to change.) от http://www.boost.org/doc/libs/1_55_0/libs/multiprecision/doc/html/boost_multiprecision/ref/cpp_dec_ref.html

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

В качестве альтернативы я бы порекомендовал вам взять строковое представление cpp_dec_float и разделить его на две части самостоятельно, используя string или char* конструкторов для основных интегральных типов вы заинтересованы в.

+0

+1, с дополнительной заметкой, что публичная лицензия Boost позволяет копировать практически для любого использования, в том числе и для коммерческих. Если внутреннее представление, если какая-либо версия является именно тем, что требуется/хочет OP, то если владельцы Boost.MultiPrecision не могут быть уверены в том, чтобы заморозить одну реализацию, OP может ее заморозить самостоятельно. – AnthonyFoiani

Смежные вопросы