vexyro Posted February 10, 2012 Report Posted February 10, 2012 Conform documenta?iei Java se ?tie ca în Java, spre deosebire de C/C++ tipul de dat? long are o reprezentare pe 64bit (cu semn), iar int este reprezentat pe 32bit (tot cu semn). Bun.Acum hai s? vedem practic ce se intampl?. Lu?m cazu lui intMai întâi ocup?m doar 16/32bit cu "1"int i = 0x0000ffff;System.out.println(i); //Output: 65535System.out.println(Integer.toBinaryString(i)); //Output: 1111111111111111System.out.println(Integer.toBinaryString(i).length()); //Output: 16Hai s? vedem pentru 32/32bit umplu?i cu "1"int i = 0x7fffffff;System.out.println(i); //Output: 2147483647System.out.println(Integer.toBinaryString(i)); //Output: 1111111111111111111111111111111System.out.println(Integer.toBinaryString(i).length()); //Output: 31int i = 0xffffffff;System.out.println(i); //Output: -1System.out.println(Integer.toBinaryString(i)); //Output: 1111111111111111111111111111111System.out.println(Integer.toBinaryString(i).length()); //Output: 32Totul pare în regul? pân? acum. Rezultatul e clar de ce este "-1".S? vedem pentru longMai întâi ocup?m doar 16/64bit cu "1"long i = 0xffff;System.out.println(i); //Output: 65535System.out.println(Long.toBinaryString(i)); //Output: 1111111111111111System.out.println(Long.toBinaryString(i).length()); //Output: 16Ce se întampl? pentru 32/64bit umplu?i cu "1" devine suspect in cazul ((a)long i = 0x7fffffff;System.out.println(i); //Output: 2147483647System.out.println(Long.toBinaryString(i)); //Output: 1111111111111111111111111111111System.out.println(Long.toBinaryString(i).length()); //Output: 31(long i = 0xffffffff;System.out.println(i); //Output: -1System.out.println(Long.toBinaryString(i)); //Output: 1111111111111111111111111111111111111111111111111111111111111111System.out.println(Long.toBinaryString(i).length()); //Output: 64P?i long asta e lung sau e int ? Rezultatul teoretic nu ar fi trebuit s? fie ?sta ?System.out.println(i); //Output: 4294967295System.out.println(Long.toBinaryString(i)); //Output: 11111111111111111111111111111111System.out.println(Long.toBinaryString(i).length()); //Output: 32Din ce am observat eu abia în cazul (i este transformat într-un QWord. Pân? atunci pare s? se comporte ca un DWord.B?nuiesc c? dac? exist? o exliplica?ie logic?, este una idioat? la care nu m-a? fi gândit (prea curând) Quote
M2G Posted February 10, 2012 Report Posted February 10, 2012 long i = 0xffffffff;System.out.println(i); //Output: -1System.out.println(Long.toBinaryString(i)); //Output: 1111111111111111111111111111111111111111111111111111111111111111System.out.println(Long.toBinaryString(i).length()); //Output: 64Tu declari acea variabila long i dar ii atribui defapt un int. De asta se comporta asa.Corect trebuie scris asa:long i = 0x7fffffffffffffffL; System.out.println(i); //Output: 9223372036854775807 System.out.println(Long.toBinaryString(i)); //Output: 111111111111111111111111111111111111111111111111111111111111111 System.out.println(Long.toBinaryString(i).length()); //Output: 63 Quote
cmiN Posted February 10, 2012 Report Posted February 10, 2012 In C++ facea cast dupa containerul in care urma sa intre, dar aici am impresia ca trebuie sa fortezi, probabil o avea limbajul un sistem mai inteligent prin care iti economiseste memoria, intrebarea este ce se intampla daca dupa ce ii dai lui long i = 0x7fFFffFF faci i *= i ? Quote
M2G Posted February 10, 2012 Report Posted February 10, 2012 (edited) Pentru long i = 0x7fFFffFFL iti face inmultirea normal pentru ca rezultatul i*=i nu depaseste 64biti. long i = 0x7fffffffL; i*=i; System.out.println(i); //Output: 4611686014132420609 System.out.println(Long.toBinaryString(i)); //Output: 11111111111111111111111111111100000000000000000000000000000001 System.out.println(Long.toBinaryString(i).length()); //Output: 62Daca te referi la long i = 0x7fFFffFFffFFffFFL, rezultatul lui i*=i o sa fie 1. long i = 0x7fffffffffffffffL; i*=i; System.out.println(i); //Output: 1 System.out.println(Long.toBinaryString(i)); //Output: 1 System.out.println(Long.toBinaryString(i).length()); //Output: 1Pentru numere mari se poate folosi clasa BigInteger care nu prea are limita decat cantitatea de date care incape in memoria RAM. Edited February 10, 2012 by M2G Quote
cmiN Posted February 10, 2012 Report Posted February 10, 2012 Ok si pentru (64bit) 0xffFFffFF * 0xffFFff00 fara acel L la sfarsit va da -1*(x) == -x sau valoarea normala ? Quote
wildchild Posted February 10, 2012 Report Posted February 10, 2012 (edited) Citeste despre atomicitate si volatilitate...O operatie este atomica daca ea nu poate fi intrerupta de thread schedulerEx de operatii atomice: operatii simple executate pe tipuri primitive altele decat long si double (pe sisteme 32 biti)Vizibilitate: modificari efectuate de un task chiar daca acestea sunt atomice, pot sa nu fie vizibile altor taskuri (de ex. Valoarea modificata a variabilei poate fi stocata intr-un registru temporar)Mecanismul de sincronizare forteaza ca modificarile unui task sa fie vizibile in toata aplicatia, chiar si pe multiprocesorCuvantul cheie volatile: asigura vizibilitatea: imediat ce un thread scrie o valoare intr-o variabila volatile, acea valoare va fi disponibila pt readEste safe sa utilizam volatile in loc de synchronized, doar daca clasa are un singur camp care poate fi modificatedit: un test de atomicitate import java.util.concurrent.*;public class AtomicityTest implements Runnable { private int i = 0; public int getValue() { return i; } private synchronized void evenIncrement() { i++; i++; } public void run() { while(true) evenIncrement(); } public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); AtomicityTest at = new AtomicityTest(); exec.execute(at); while(true) { int val = at.getValue(); if(val % 2 != 0) { System.out.println(val); System.exit(0); } } }} Edited February 10, 2012 by wildchild Quote
Xander Posted February 10, 2012 Report Posted February 10, 2012 cand dai long i = 0xffffffff; iti traduce in ceva de genul:int k = 0xffffffff;long i = k;si afiseaza corect -1 (daca vrei sa vezi pune 9 f inloc de 8 (0xfffffffff) si vezi exact ce zice daca vrei longlong i = 0xffffffffL;si merge cum te astepti Quote
M2G Posted February 10, 2012 Report Posted February 10, 2012 Deci cand declari un long i = 0xffFFffFF si nu pui L, acea valoare este considerata ca un int(adica e o valoare pe 32 biti). Daca de exemplu ai long i = 0xffFFffFF+1 rezultatul o sa fie 0 si e echivalent cu int i = 0xffFFffFF +1.Dar daca ai long i = 0xffFFffFFL+1 rezultatul o sa fie valoarea maxima din int +1, adica 4294967296 pe 33 biti (100000000000000000000000000000000) Quote