2013-05-10 21 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 - 或我的号码的基础数据。

也就是说,我喜欢这样的事情存在:

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#十进制类型。请参阅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 

但是,如果它在未来的版本打破了,你得两件。


嘿,感谢您的downvote没有评论。这真的很有帮助。

为了澄清上述我的意见:

使用eval_frexp:经过进一步的研究,似乎eval_frexp(b, cb, pi)仍然是2只提供权力,似乎是需要为Decimal型不是10的权力。所以我怀疑如果你只想使用公共接口,你必须以长的形式进行算术。

滥用private成员:Boost.Multiprecision类的作者和维护者根据某些准则设计了它们;他们明显地将未来防御定义为比提供对内部结构的访问更重要:

类模板cpp_dec_float满足后端类型的所有要求。其成员和非成员职能故意没有记录:这些被视为实施细节,可能会有变化。 (http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/boost_multiprecision/ref/cpp_dec_ref.html

我的建议,这是清晰的“淘气”,并警告说,这可能会在未来的版本中突破,是提前征收那些作者的OP的设计需求B.MP.

最简洁的方法可能是建议更改cpp_dec_float类,其中暴露内部结构;给出一个引人注目的用例,并分析代码历史上有多少或没有变化,它甚至可能被接受。

希望这会有所帮助。如果读者仍然有问题,请随时放弃,但请让我知道哪个部分困扰你,所以我可以尝试改进它。

+0

不是我干的,但'#define'ing关键字是未定义的行为,(几乎?)从来没有一个可靠的解决方案 – 2014-06-23 15:32:45

+0

哦,没有论据。我试图说出最初的答复(以及我对downvote的评论),清楚地表明这不是用于生产的好主意。如果OP真的需要长期的这种能力,那么如果他们不能说服B.MP维护者,他们应该分叉它并将其吸收到它们的代码库中--BPL允许这样做。我只是想提供一个“这是晚上11点,你明天需要它”的解决方案。也许这值得赞扬,不知道。 – AnthonyFoiani 2014-06-25 05:45:44

+0

有趣的轶事:我试图在我现在的公司内部的meme生成器上创建一个“#define private public; NO REGRETS”meme ...只是被重定向到一个*现有的*例子。所以我猜想我并不是这个想法中唯一痴迷的灵魂。 :) – AnthonyFoiani 2014-06-25 05:52:06

0

我不知道这是不是你正在寻找,尝试...

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

的类型仍然是cpp_dec_float_100,但只包含整数部分。 我希望这可以帮助。

1

从boost文档中,后端是故意不透明的,因为它随时可能会更改而不会发出警告。 (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

据我所见,你在这里有两个选择。您可以查看所用后端类的特定版本的源代码,使用backend方法从number访问它,并希望后端永远不会发生更改(尤其是考虑只会破坏二进制格式而不编译的更改) 。

或者我会建议您采取cpp_dec_float的字符串表示,并将其分成两个部分自己,使用stringchar*构造的底层整数类型你感兴趣的内容。

+0

+1,附加注意,Boost公共许可证允许复制几乎任何用途,包括商业用途。如果内部表示如果某个版本正是OP需要/想要的内容,那么如果Boost.MultiPrecision所有者无法确信冻结一个实现,则OP可以自行冻结它。 – AnthonyFoiani 2014-06-25 05:49:22