簡體   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