Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1

    [JAVA] problema con little e big endian

    Ciao a tutti, ho il seguente problema:

    double var;

    DataInputStream dis = new DataInputStream(new FileInputStream ("weights.dat"));

    ByteBuffer bb = ByteBuffer.allocate(9000);
    bb.order(ByteOrder.LITTLE_ENDIAN);

    for(int i=0;i<896.;i++)
    {
    var=dis.readDouble();
    bb.putDouble(i,var);
    System.out.println(var +" "+ bb.getDouble(i) +" "+i);
    }

    Con il seguente output:

    0.009182359616844394__0.009182359616844394__0
    -0.002138954759412613__-0.002138954759412613__1
    0.005195382598750681__0.005195382598750681__2
    4.819424459599818__4.819424459599818__3
    5.058553871334569__5.058553871334569__4
    1.0871459521596347__1.0871459521596347__5
    -1.0868843071228302__-1.0868843071228302__6
    -0.0016712652843744874__-0.0016712652843744874__7
    0.0012012366699741682__0.0012012366699741682__8
    -0.001529889658280872__-0.001529889658280872__9
    2.295218951725268__2.295218951725268__10
    ..............................numeri uguali fino a 895

    Quindi la funzione di conversione da big_endian a little_endian non mi converte. Sapete dirmi come si fa a farla funzionare???

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [JAVA] problema con little e big endian

    Originariamente inviato da vatastala
    Quindi la funzione di conversione da big_endian a little_endian non mi converte. Sapete dirmi come si fa a farla funzionare???
    Non funziona perché il put e il get sul ByteBuffer lo fa sempre come little-endian!!! Devi impostare l'ordine a little-endian, inserire il double nel buffer, quindi cambiare l'order a big-endian e infine leggere il double.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Scusa non ho capito come fare, me lo scrivi please???

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da vatastala
    Scusa non ho capito come fare, me lo scrivi please???
    - Crei il tuo ByteBuffer, come hai fatto tramite allocate()
    - Imposti l'order little-endian, come hai fatto tramite order(ByteOrder.LITTLE_ENDIAN)
    - Fai il put del double
    - Imposti l'order big-endian, tramite order(ByteOrder.BIG_ENDIAN)
    - Fai il get del double

    C'è solo uno step in più ... quello per impostare il big-endian.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Originariamente inviato da andbin
    - Crei il tuo ByteBuffer, come hai fatto tramite allocate()
    - Imposti l'order little-endian, come hai fatto tramite order(ByteOrder.LITTLE_ENDIAN)
    - Fai il put del double
    - Imposti l'order big-endian, tramite order(ByteOrder.BIG_ENDIAN)
    - Fai il get del double

    C'è solo uno step in più ... quello per impostare il big-endian.
    Scusa ma non funziona proprio, l'output è sempre lo stesso

    DataInputStream dis = new DataInputStream(new FileInputStream ("weights.dat"));

    ByteBuffer bb = ByteBuffer.allocate(9000);
    // bb.order(ByteOrder.LITTLE_ENDIAN);

    for(int i=0;i<896.;i++)
    {
    var=dis.readDouble();
    bb.putDouble(i,var);
    // bb.order(ByteOrder.BIG_ENDIAN);
    System.out.println(var +"__"+ bb.order(ByteOrder.BIG_ENDIAN).getDouble(i) +"__"+i);
    }

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da vatastala
    Scusa ma non funziona proprio, l'output è sempre lo stesso

    DataInputStream dis = new DataInputStream(new FileInputStream ("weights.dat"));

    ByteBuffer bb = ByteBuffer.allocate(9000);
    // bb.order(ByteOrder.LITTLE_ENDIAN);

    for(int i=0;i<896.;i++)
    {
    var=dis.readDouble();
    bb.putDouble(i,var);
    // bb.order(ByteOrder.BIG_ENDIAN);
    System.out.println(var +"__"+ bb.order(ByteOrder.BIG_ENDIAN).getDouble(i) +"__"+i);
    }
    Quando fai il put deve essere little-endian, quando fai il get deve essere big-endian (o il contrario, tanto devi solo swappare). Little-endian lo imposti solo 1 volta prima del for!!!!

    E poi scusa, perché fai un ByteBuffer di 9000 e nel for inserisci ogni volta all'offset 'i'??? Così fai un macello (oltre a sprecare memoria).

    Vuoi swappare un double?? Bene, crea il tuo ByteBuffer lungo 8, poi ad ogni ciclo fai:
    a) un clear() del ByteBuffer
    b) un order(...) per impostare little-endian
    c) il put del double
    d) un order(...) per impostare big-endian
    e) un get del double

    Spendi anche solo 5 minuti del tuo tempo per capire meglio come funziona ByteBuffer!!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Originariamente inviato da andbin
    Quando fai il put deve essere little-endian, quando fai il get deve essere big-endian (o il contrario, tanto devi solo swappare). Little-endian lo imposti solo 1 volta prima del for!!!!

    E poi scusa, perché fai un ByteBuffer di 9000 e nel for inserisci ogni volta all'offset 'i'??? Così fai un macello (oltre a sprecare memoria).

    Vuoi swappare un double?? Bene, crea il tuo ByteBuffer lungo 8, poi ad ogni ciclo fai:
    a) un clear() del ByteBuffer
    b) un order(...) per impostare little-endian
    c) il put del double
    d) un order(...) per impostare big-endian
    e) un get del double

    Spendi anche solo 5 minuti del tuo tempo per capire meglio come funziona ByteBuffer!!
    Ho fatto esattamente come dici tu, almeno credo:

    DataInputStream dis = new DataInputStream(new FileInputStream ("weights.dat"));

    ByteBuffer bb = ByteBuffer.allocate(8);

    for(int i=0;i<896.;i++)
    {
    bb.clear();
    var=dis.readDouble();
    bb.order(ByteOrder.LITTLE_ENDIAN).putDouble(var);
    System.out.println(var +"__"+ bb.order(ByteOrder.BIG_ENDIAN).getDouble(0) +"__"+i);
    }

    E in output ho:

    0.009182359616844394__3.2988478350696204E-120__0
    -0.002138954759412613__-1.0002030903222078E291__1
    0.005195382598750681__-1.3020882548998934E-28__2
    4.819424459599818__1.732336501769424E15__3
    5.058553871334569__-2.5247218293340496E-141__4
    1.0871459521596347__1.2730424913726184E-221__5
    -1.0868843071228302__8.841273238611073E-299__6
    -0.0016712652843744874__-12.159056048998421__7
    0.0012012366699741682__-1.2707150916632518E11__8
    -0.001529889658280872__-7.596228970545135E118__9
    2.295218951725268__5.60797856292581E-70__10

    Grazie mille per il tuo aiuto, dimmi solo se reputi corretti gli output e se devo tornare ad allocare un Buffer come prima visto che dopo devo fare la seguente operazione, per riportare il file dei pesi originale (in little endian) in un file dei pesi in big endian:

    FileChannel out = new FileOutputStream ("weightsOUT.dat").getChannel();
    out.write (bb);
    out.close ();

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da vatastala
    E in output ho:

    0.009182359616844394__3.2988478350696204E-120__0
    -0.002138954759412613__-1.0002030903222078E291__1
    0.005195382598750681__-1.3020882548998934E-28__2
    4.819424459599818__1.732336501769424E15__3
    5.058553871334569__-2.5247218293340496E-141__4
    1.0871459521596347__1.2730424913726184E-221__5
    -1.0868843071228302__8.841273238611073E-299__6
    -0.0016712652843744874__-12.159056048998421__7
    0.0012012366699741682__-1.2707150916632518E11__8
    -0.001529889658280872__-7.596228970545135E118__9
    2.295218951725268__5.60797856292581E-70__10

    Grazie mille per il tuo aiuto, dimmi solo se reputi corretti gli output
    In che senso ... io non so se i tuoi dati sono giusti! A parte il fatto che non sarebbe certo l'ideale stampare un double swappato al contrario, in quanto il numero è sicuramente "a palla".
    Ad esempio 8.841273238611073E-299 mi sembra del tutto sballato mentre -1.0868843071228302, che è quello che hai letto dal DataInputStream, mi sembra più normale.

    Da quello (poco) che ho capito io, ciò che ricevi dal DataInputStream è al contrario, ed è per questo che vuoi swapparlo (giusto?). Ma se è giusto quello in 'var', lo swap lo sballa del tutto, che lo swappi a fare? .... insomma, non so se ci siamo capiti.

    Tra l'altro, se si usa Java 5 o superiore c'è un modo molto più semplice per swappare un double:

    double input;
    double swapped = Double.longBitsToDouble (Long.reverseBytes (Double.doubleToRawLongBits (input)));
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Originariamente inviato da andbin
    In che senso ... io non so se i tuoi dati sono giusti! A parte il fatto che non sarebbe certo l'ideale stampare un double swappato al contrario, in quanto il numero è sicuramente "a palla".
    Ad esempio 8.841273238611073E-299 mi sembra del tutto sballato mentre -1.0868843071228302, che è quello che hai letto dal DataInputStream, mi sembra più normale.

    Da quello (poco) che ho capito io, ciò che ricevi dal DataInputStream è al contrario, ed è per questo che vuoi swapparlo (giusto?). Ma se è giusto quello in 'var', lo swap lo sballa del tutto, che lo swappi a fare? .... insomma, non so se ci siamo capiti.

    Tra l'altro, se si usa Java 5 o superiore c'è un modo molto più semplice per swappare un double:

    double input;
    double swapped = Double.longBitsToDouble (Long.reverseBytes (Double.doubleToRawLongBits (input)));
    No non lo devo swappare!!! Io ho un file dei pesi i cui valori sono stati ottenuti con java, quindi a quanto ho capito ogni double è codificato in little endian...Io lo devo convertire in un file dei pesi in big endian per C++, perchè mi è stato detto che i 2 linguaggi usano codifiche diverse.

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da vatastala
    perchè mi è stato detto che i 2 linguaggi usano codifiche diverse.
    E ti hanno detto molto male..... perché il big/little-endian non centra una mazza con i linguaggi di programmazione.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.