簡體   English   中英

具有模數的boost多精度庫的不一致性

[英]Inconsistency in boost multiprecision library with modulus

我看到一些與boost multiprecision庫不一致,使用cpp_int,並想知道問題是否在我的最后? 難道我做錯了什么?

boost::multiprecision::cpp_int value("845812507058753702096720396260955981034309941487979439207575316627396775257009179367680598562088782400182102510047921049667535737841056751035898984440045398065941794853342721440022891483618946596390530332584847468817849746783423105644934675762519035784877729169739110084935079201004991911753548016158266946593610497793934212345180527788034865286995713462176706647193473406223095268503330593499438446017000593156395272905592017851490768402042283892535127698736772114426168690580061412400354553387531076676433901465842118416610671452446364936252601684680593015917270112975907856081311621268680168563153055479531193987696015767888543608430149655940111761214342848772129089336344636193634262254610730");
boost::multiprecision::cpp_int residueResult = value % 733;
std::cout << residueResult;                      // this prints out 4
int residue1 = residueResult.convert_to<int>();  // this is 4
int residue2 = int(value % 733);                 // this is 1

為什么在執行int(值%733)時它給出的值為1?

這是使用boost 1.59.0和visual studio 2013社區。

第二次演員表無效,不應該編譯。

GCC

test.cpp|9 col 35| error: invalid cast from type ‘boost::enable_if_c<true, boost::multiprecision::detail::expression<boost::multiprecision::detail::modulus_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<> >, int, void, void> >::type {aka boost::multiprecision::detail::expression<boost::multiprecision::detail::modulus_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<> >, int, void, void>}’ to type ‘int’
||      int residue2 = int(value % 733);                 // this is 1

test.cpp|9 col 20| error: cannot convert 'typename enable_if_c<is_compatible_arithmetic_type<int, number<cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_int_check_type::unchecked, allocator<unsigned long long> >, et_on> >::value && (number_category<cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_int_check_type::unchecked, allocator<unsigned long long> > >::value == number_kind_integer), detail::expression<detail::modulus_immediates, number<cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_int_check_type::unchecked, allocator<unsigned long long> >, et_on>, int> >::type' (aka 'boost::multiprecision::detail::expression<boost::multiprecision::detail::modulus_immediates, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0, 0, boost::multiprecision::cpp_integer_type::signed_magnitude, boost::multiprecision::cpp_
|| nt_check_type::unchecked, std::__1::allocator<unsigned long long> >, boost::multiprecision::expression_template_option::et_on>, int, void, void>') to 'int' without a conversion operator
||     int residue2 = int(value % 733);                 // this is 1
||                    ^~~~~~~~~~~~~~~

推測

如果您實際上已經以不同的方式編寫了這些內容,那么您可能已經獲得了reinterpret_cast,因此結果是實現定義的。

UPDATE

評論:

住在Coliru

#include <boost/multiprecision/cpp_int.hpp>
#include <cstdio>

int main() {
    using Int = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off>;
    Int value("845812507058753702096720396260955981034309941487979439207575316627396775257009179367680598562088782400182102510047921049667535737841056751035898984440045398065941794853342721440022891483618946596390530332584847468817849746783423105644934675762519035784877729169739110084935079201004991911753548016158266946593610497793934212345180527788034865286995713462176706647193473406223095268503330593499438446017000593156395272905592017851490768402042283892535127698736772114426168690580061412400354553387531076676433901465842118416610671452446364936252601684680593015917270112975907856081311621268680168563153055479531193987696015767888543608430149655940111761214342848772129089336344636193634262254610730");

    printf("residue %d:\n", int(value % 733));
}

打印

residue 4:

手頭的問題是value % 733是一些實現細節代理類型,你不能只將它轉換為int 實際上,這甚至都沒有用gcc和clang編譯,正如你所看到的那樣,它會產生無意義的MSVC。 要解決這個問題,請在轉換之前轉換回cpp_int

int main () {
    boost::multiprecision::cpp_int value("845812507058753702096720396260955981034309941487979439207575316627396775257009179367680598562088782400182102510047921049667535737841056751035898984440045398065941794853342721440022891483618946596390530332584847468817849746783423105644934675762519035784877729169739110084935079201004991911753548016158266946593610497793934212345180527788034865286995713462176706647193473406223095268503330593499438446017000593156395272905592017851490768402042283892535127698736772114426168690580061412400354553387531076676433901465842118416610671452446364936252601684680593015917270112975907856081311621268680168563153055479531193987696015767888543608430149655940111761214342848772129089336344636193634262254610730");
    boost::multiprecision::cpp_int residueResult = value % 733;
    std::cout << residueResult << "\n";                      // this prints out 4
    int residue1 = residueResult.convert_to<int>();  // this is 4
    int residue2 = static_cast<int>(boost::multiprecision::cpp_int(value % 733));                

    std::cout << residue1 << "\n" << residue2;
}

這將打印

4
4
4

如預期的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM