2010-02-22 10 views
7

Mam dziwny problem z C++, gdzie długi typ danych przepełnia się na długo przed tym powinien. Co robię (z dotychczasowym sukcesem) to, że liczby całkowite zachowują się jak pływaki, więc zakres [-32767,32767] jest odwzorowany na [-1,0,0]. Gdzie natyka się z większymi argumenty reprezentujące płynie większy niż 1,0:C++ długo przelewa się przedwcześnie

inline long times(long a, long b) { 
    printf("a=%ld b=%ld ",a,b); 
    a *= b; 
    printf("a*b=%ld ",a); 
    a /= 32767l; 
    printf("a*b/32767=%ld\n",a); 
    return a; 
} 

int main(void) { 
    printf("%ld\n",times(98301l,32767l)); 
} 

Co otrzymuję jako wyjście jest:

a=98301 b=32767 a*b=-1073938429 a*b/32767=-32775 
-32775 

So razy (98301,32767) jest analogiczna do 3.0 * 1.0. Ten kod działa doskonale, gdy argumenty do czasów są mniejsze niż 32767 (1.0), ale żaden z pośrednich kroków z powyższymi argumentami nie powinien przepełnić 64 bitów długości.

Wszelkie pomysły?

+0

Czy akceptujesz odpowiedź, to sprawia, że ​​ludzie chętniej pomogą ci w przyszłości. –

Odpowiedz

9

długi niekoniecznie jest 64-bitowy. spróbuj zamiast tego "długo".

+0

To działa! Dziękujemy wszystkim, którzy zasugerował to, co męczące. Sprawia, że ​​doceniam Javę o wiele więcej ... – rhodri

+0

@rhodri: długo nie jest koniecznie 64-bitowe, nawiasem mówiąc (w niektórych implementacjach). Sprawdź Zwiększ liczbę całkowitą lub sprawdź, czy Twój kompilator ma stdint.h. – GManNickG

+1

@GMan: Prawidłowo. Jednak standardowe C gwarantuje, że 'długo long' ma zasięg * * wystarczającą dla 64-bitowej liczby całkowitej, a to wystarczy zwykle ... – sleske

2

Prawdopodobnie masz 32-bitowe długości. Zamiast tego spróbuj użyć long long.

98301 * 32767 = 3221028867, podczas gdy 32-bitowa długo przepełnienia w 2147483648

4

TYPE long niekoniecznie jest 64 bitów. Jeśli korzystasz z architektury 32-bitowej (przynajmniej w MS Visual C++), typ long ma 32 bity. Sprawdź to pod numerem sizeof (long). Istnieje również typ danych long long, który może pomóc.

2

C średnia gwarantuje jedynie, że long będzie miała co najmniej 32 bit (co jest rzeczywiście sprawa na większości platform 32-bitowych). Jeśli potrzebujesz 64-bitowego, użyj long long. To gwarantuje co najmniej 64-bitową.

Powiązane problemy