[英]long long int on 32-bit Linux vs 64-bit Linux and MPFR
与64位Linux相比,32位Linux系统如何精确地处理long long int
?
在我的32位系统上,我对MPFR数据类型使用C ++包装器 ; 这个包装器的构造器是为long int
定义的,而不是long long int
。 但是,在32位系统上,此代码仍然有效:
long long int i=5LL;
mpreal myVar(i);
cout<< "this was constructed with a long long int:" <<myVar <<endl;
这怎么可能? 请问32位的gcc不知怎么竟投下long long int
成说long int
为其mpreal
数据类型确实有一个构造函数? 如果以上代码在64位Linux上运行,则编译器将导致有关构造不明确的错误。
我知道有人会告诉我不要在64位上完全使用long long int
,但是不幸的是,我使用的是另一个库(odeint),该库内置于代码中,以这种方式构造给定的多精度数据类型,所以我认为我不能改变事情。
是long long int
完全一样long int
在64位呢? 如果我转换为long int
会丢失数据吗? 例如,如果我将自己的构造函数设为:
mpreal(const long long int u, mp_prec_t prec, mp_rnd_t mode)
{
mpfr_init2(mp,prec);
mpfr_set_si(mp, u, mode);
}
我问了mpreal.h的作者(完整的答案在http://www.holoborodko.com/pavel/mpfr/#comment-7444 ),首先是关于在64x系统上为long long int
构建新的构造函数:
>Functions “mpfr_set_ui/si” should be fine.
>Basically constructor for “long long int” should be equivalent to “long int” one.
>GNU GCC system makes porting from x32 to x64 a little bit messy. It automatically
>upgrades integer types to x64 bits, which could easily break code being ported.
>The best workaround for GCC would be to use types with explicit number of bits:
>int32_t, int64_t from stdint.h. Then move from x32 to x64 would be painless.
>However neither authors of MPFR nor developers of numeric libraries follow this
>standard using “long long int”, “long int”, “intmax_t” all of which means different
>things on x32 and x64 in GCC world.
>There is some macro-logic in mpreal.h which tries to make things smooth:
>(a) for x32 builds we define additional constructors for int64_t (aka “long long int”
>or “intmax_t” )
>(b) for x64 builds we remove constructors for such type since “long int” is already
>64bit wide.
>Macro MPREAL_HAVE_INT64_SUPPORT plays only “suggestive” role, it is undefined
>automatically for x64 builds on GCC to avoid clash among integer types.
>The better way would be to detect bit resolution of all integer types at compile time
>(using macros or meta-magic similar to boost) and add suitable routines to mpreal
>class. This could easily grow to be more complex than mpreal itself :) .
>Maybe I will come up with better solution in future versions, any suggestions are
>welcome.
因此,我认为从OP构建我的构造函数将使x64系统上的内容可以正常运行,但是如果返回x32系统,则需要再次将其删除,否则将导致冲突。 原因是在32x上定义了MPREAL_HAVE_INT64_SUPPORT
宏,并定义了int64_t
构造函数(在32x上又名long long int
),因此添加另一个这样的构造函数将导致冲突。 这也是我的代码在32位系统上开箱即用的原因。 在64x系统上,未定义MPREAL_HAVE_INT64_SUPPORT
宏,并且删除了此类构造函数,因为long int
已经是64位宽了,因此作者无需使用long long int
构造函数。
对于各种类型的大小,请检查C标准 , long long
必须用至少64位表示。
要查看编译器对代码的实际作用,可以在二进制文件(或中间目标文件)上使用objdump -D
。
在32位拱上,如果从long long
到long
投射, 将会丢失数据。
据我了解,编译器可能难以确定要使用哪个构造函数(基本上无法决定使用ctor(int)
还是ctor(long int)
)。
编辑:
#include <stdint.h>
...
uint64_t x = 5;
mpreal myVar(i);
就像定义了c-tor(uint64_t)
(或者最好说可以找到明确的匹配项)-因为在64位arch上, (unsigned) long int
等效于uint64_t
(对于glibc,它实际上是这样定义的)。 错误是由编译器在处理重载函数时使用的规则引起的-有关更多信息,请参见C ++ 11标准 / 草稿 。
一般而言,如果您希望代码可移植,则应使用inttypes.h
或stdint.h
定义的类型uintXX_t
- uintXX_t
和intXX_t
。 这些类型保证可以提供确切的宽度,有关更多信息,请参见上面的Wiki链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.