» »

[C]Večni problem - C in 64 bitov

[C]Večni problem - C in 64 bitov

Ezekiel ::

Zdravo!

Kot že nekaj časa nazaj:
tip spremenljivke long int (oziroma long long int) naj bi imel dolžino 64 bitov (8 bajtov). Do tukaj vse lepo in prav, ampak, recimo da potrebujem število oblike
11110000000000000000000000000000 00000000000000000000000000000000

kjer je na desni potem 60 ničel ... Seveda, v najslabšem primeru vzamem število
(1 << 4) - 1
in ga premaknem v levo za 60 mest. Ampak, rezultat operacije je
00000000000000000000000000000000 0000000000000000000000000000000 

same ničle. Torej, nekaj ni uredu. V primeru, da zadeva zaseda manj kot 32 mest (torej leži v desni polovici teh 64 bitov) je vse ok, ko pa gre preko 32. bita se spremeni v nerazpoznavno packo. Primer:
(unsigned long long int)(((1 << 5)-1) << 27)
11111111111111111111111111111111 11111000000000000000000000000000

moglo bi pa bit
00000000000000000000000000000000 11111000000000000000000000000000

Še podatki:
sistem: Ubuntu 5.10 za Amd 64
IDE: Kdevelop 3.2.3
GCC 4.0.2

vklopljeni CFLAGS:
normalni: -O3 -g3 -std=c99
athlon specific: -m64 -march=athlon64 -mno-align-double

pri slednjih sem uporabil še recimo -mlong64, pa ne deluje...

Torej, kako naj dobim tistih 64 bitov, ki jih vrača sizeof()?

Hvala

OwcA ::

Če drugega ne, ti ostane hackanje s kazalci in tipi.
Otroška radovednost - gonilo napredka.

Ezekiel ::

kaj si lahko malo bolj natančen?

no, bom proval še v HEX formatu noter števile šopat, ker to vsi v člankih delajo pa bomo vidli...

Ezekiel ::

ok...

rešitev:
na koncu števila dodaš ULL , UL, L

torej nekako tako:
unsigned long a = 0x000000000000000FUL
//ali pa d = 15UL;

printf("%lld: ", d);

d <<= 40ULL;
printf("%lld: ", d);


u glavnem, povsod kjer imaš opravka z long al pa long long dodaš na konec številke L, UL, LL...

Upam, da komu pomaga...

EDIT: pretvorbe v stilu
d = (unsigned long) 5;

ne delujejo...

Zgodovina sprememb…

  • spremenil: Ezekiel ()

JerKoJ ::

Tuki je koda sicer za c++, ampak mislm da ni velike razlike proti c-ju.
operacija << dela brez problemov.

#include <iostream>
#include <cmath>

typedef unsigned long long uint64;

std::string get_bin(uint64 a) {
  uint64 c=a;
  std::string s;
  for (int i=0;i<64;i++) {
    uint64 b=c%2;
    c/=2;
    if (b==0) {
      s=s.append(1,'0');
    } else {
      s=s.append(1,'1');
    }
  }
  std::reverse(s.begin(),s.end());
  return s;
}

int main() {
  uint64 a;
  a=15;
  std::cout<<get_bin(a)<<std::endl;
  for (int i=0;i<15;i++) {
    a=(a<<4);
    std::cout<<get_bin(a)<<std::endl;  
  }
  return 0;
}


output, ki ga dobim (gcc version 3.4.4 20050209 (prerelease) (Debian 3.4.3-9ubuntu4), 32-bit atlhon 1600+)

0000000000000000000000000000000000000000000000000000000000001111
0000000000000000000000000000000000000000000000000000000011110000
0000000000000000000000000000000000000000000000000000111100000000
0000000000000000000000000000000000000000000000001111000000000000
0000000000000000000000000000000000000000000011110000000000000000
0000000000000000000000000000000000000000111100000000000000000000
0000000000000000000000000000000000001111000000000000000000000000
0000000000000000000000000000000011110000000000000000000000000000
0000000000000000000000000000111100000000000000000000000000000000
0000000000000000000000001111000000000000000000000000000000000000
0000000000000000000011110000000000000000000000000000000000000000
0000000000000000111100000000000000000000000000000000000000000000
0000000000001111000000000000000000000000000000000000000000000000
0000000011110000000000000000000000000000000000000000000000000000
0000111100000000000000000000000000000000000000000000000000000000
1111000000000000000000000000000000000000000000000000000000000000

U,L se uporablja pri izpisih in konstantah.

Ezekiel ::

res je...
#include <stdio.h>

void print64(unsigned long a);

int main(void){
unsigned long d;
d = 15;
for(int i = 0; i < 16; i ++){
	print64(d);
	d <<= 4;
}

printf("\n");

d = 15UL;
for(int i = 0; i < 16; i ++){
	print64(d);
	d <<= 4UL;
}
return 0;
}

//pa se funkcija
void print64(unsigned long a){
	unsigned long bit = 1;
	for(int i = WORD_SIZE_64-1; i >= 0; i--){
		printf("%d", (a & (bit << i)) ? 1 : 0);
	}
	printf("\n");
}

in output:
0000000000000000000000000000000000000000000000000000000000001111
0000000000000000000000000000000000000000000000000000000011110000
0000000000000000000000000000000000000000000000000000111100000000
0000000000000000000000000000000000000000000000001111000000000000
0000000000000000000000000000000000000000000011110000000000000000
0000000000000000000000000000000000000000111100000000000000000000
0000000000000000000000000000000000001111000000000000000000000000
0000000000000000000000000000000011110000000000000000000000000000
0000000000000000000000000000111100000000000000000000000000000000
0000000000000000000000001111000000000000000000000000000000000000
0000000000000000000011110000000000000000000000000000000000000000
0000000000000000111100000000000000000000000000000000000000000000
0000000000001111000000000000000000000000000000000000000000000000
0000000011110000000000000000000000000000000000000000000000000000
0000111100000000000000000000000000000000000000000000000000000000
1111000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000001111
0000000000000000000000000000000000000000000000000000000011110000
0000000000000000000000000000000000000000000000000000111100000000
0000000000000000000000000000000000000000000000001111000000000000
0000000000000000000000000000000000000000000011110000000000000000
0000000000000000000000000000000000000000111100000000000000000000
0000000000000000000000000000000000001111000000000000000000000000
0000000000000000000000000000000011110000000000000000000000000000
0000000000000000000000000000111100000000000000000000000000000000
0000000000000000000000001111000000000000000000000000000000000000
0000000000000000000011110000000000000000000000000000000000000000
0000000000000000111100000000000000000000000000000000000000000000
0000000000001111000000000000000000000000000000000000000000000000
0000000011110000000000000000000000000000000000000000000000000000
0000111100000000000000000000000000000000000000000000000000000000
1111000000000000000000000000000000000000000000000000000000000000


U glavnem, sedaj deluje, čeprav ne vem, zakaj ni delovalo včeraj... mogoče je bilo potrebno računalnik restartat ... :|


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

C++ presledek med števili

Oddelek: Programiranje
161380 (1052) WarpedGone

defekt - c++

Oddelek: Programiranje
51120 (1038) Vesoljc
»

Pomnilnik in c++

Oddelek: Programiranje
242145 (1854) Gundolf
»

[C++] novi standardi in compilerji

Oddelek: Programiranje
211608 (1201) Ezekiel
»

[C/C++] unsigned long lala = -1;

Oddelek: Programiranje
51165 (1124) Vesoljc

Več podobnih tem