繁体   English   中英

在32位Linux和64位Linux和MPFR上的long long int

[英]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 longlong投射, 将会丢失数据。

  • 据我了解,编译器可能难以确定要使用哪个构造函数(基本上无法决定使用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.hstdint.h定义的类型uintXX_t - uintXX_tintXX_t 这些类型保证可以提供确切的宽度,有关更多信息,请参见上面的Wiki链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM