Italian Compattare al massimo alcuni valori

MaAncheNo

Member
Licensed User
Longtime User
..... ed in formato testo ne occupa 9 (senza contare il separatore, assolutamente necessario)...
Perché il separatore è assolutamente necessario in formato testo? Se stabilisci che i punti sono espressi sempre allo stesso modo non mi pare necessario, 4 + 4 byte:

44.123456 e 7.123456

44 = 1 byte
. = non serve
12 = 1 byte
34 = 1 byte
56 = 1 byte

e
07 = 1 byte
. = non serve
12 = 1 byte
34 = 1 byte
56 = 1 byte

Anche un intero sta in 4 byte e tenuto conto del range numerico del punti GPS perché usare float?
 
Last edited:

AlpVir

Well-Known Member
Licensed User
Longtime User
Anche se, per ipotesi, eliminassi il separatore, dovrei scrivere tutti i 7 campi allo stesso modo. Ad esempio sia il campo Reg che in campo Inv accettano valori fra 2000 a 900000 e quindi dovrei scrivere SEMPRE 002000 e addio risparmio.
La soluzione è senz'altro quella di scrivere in binario; ogni riga dovrebbe occupare 4+4+1+2+2+2+8=19 bytes (o forse meno) e allora sì che si potrebbero eliminare i separatori perchè ogni campo avrebbe la sua posizione.
Attualmente, in formato testo occupa circa 30-40 bytes.
Non so trovare la strada giusta fra Random Access File, B4XSerializator, AsyncStreamObject e compagnia bella.
 

MaAncheNo

Member
Licensed User
Longtime User
Scusa ma stavo editando il post mentre scrivevi.
Un Int occupa 4 byte e può contenere tutta l'escursione di una coordinata, si tratterebbe solo di stabilire quanti decimali usi (parte di destra dellì'int) mettere il separatore e usare il resto come parte intera reale.

l'Int va da -2147483648 a 2147483647, potresti anche usare 7 decimali, l'importante è siano fissi

99.5555555->995555555
7.4444444-> 74444444
Il separatore non è necessario usando gli Int.
 

MaAncheNo

Member
Licensed User
Longtime User
Nel tuo caso i dati sono pochi ma se dovessero crescere ci sono anche altri metodi prima di arrivare a comprimere i dati in Zip o altro e comunque risparmieresti, si tratta solo di implementare il metodo giusto.
Di seguito incollo un estratto di come che venivano scritti/trasferiti i parametri (oltre duecento valori) nelle memorie delle "scatole nere" dei treni italiani, tenendo presente che venivano scritti sempre tutti ma solo al variare di uno di essi:

B4X:
4.3.3 Formato compresso.
......
La prima riga di ciascuna zona e successivamente una riga ogni 100 devono essere memorizzate senza compressione (righe chiave).
Per le altre righe è necessario: 
calcolare i due byte di CRC sulla riga non compressa 
codificare la riga come differenza rispetto alla precedente 
aggiungere il CRC e i caratteri di CR e LF.

L’operazione di codifica della riga deve essere effettuata confrontando ciascun carattere della riga con il corrispondente di quella precedente, contando il numero di caratteri uguali e scrivendo tale numero utilizzando i caratteri riservati dal 128 al 255.  I caratteri diversi sono scritti inalterati....    Seguiva un esempio in Pascal

Tuttavia con i pochi dati che devi trasferire credo si tratti molto di forma e poco di sostanza, nel senso che non puoi arrivare ad avere un risparmio esagerato in qualunque modi si provi.
 

udg

Expert
Licensed User
Longtime User
Per comodità vi riporto qui dis eguito lo spazio occupato e i range di validità dei vari tipi di dato disponibili in java e qundi in B4x:
B4X:
Byte : 1byte signed: -128 to 127
Char : 2bytes unsigned: 0 to 65535 : not all values are valid Unicode code points
Short : 2bytes signed: -32768 to 32767
Int : 4bytes signed: -2147483648 to 2147483647
Long : 8bytes signed: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (9.2...E+18)
Float : 4bytes +/- 3.4e +/- 38 (~7 digits)
Double : 8bytes +/- 1.7e +/- 308 (~15 digits)

Da cui direi che portare Float ad Integer non produca risparmio. Bisognerebeb evdere se alcuni dati possono rientrare tra i Byte o Short invece che Integer.
Ad esempio, se la data potesse essere registrata un'unica volta e poi sui record sucecssivi avere solo ora e minuti codificati come byte.

020171029
144.12345607.123456...1123 - posizione alle 11:23
144,12345507.123333...1133 - posizione alle 11:33
dove il primo byte indica se si tratta di un record data (0) oppure di un record con la registrazione di un evento (1)
Non sapendo cosa indichimo H, Reg, Inv.. e quali possano essere i loro valori quello di sopra è un'idea di come ridurre 8 byte di long in 2 byte di ora/minuti portando la data su un record a sè; considerando il byte iniziale per il tipo, si avrebbe un risparmio di 5 byte per ciascun record evento.

ps: è un'idea come un'altra e può essere ancora ottimizzata se si conoscono dei vincoli specifici (es. le ore vanno necessariamente da 0 a 23 oppure quelel valide sono solo dalle 6 alle 18, tanto per fare un esempio?).
 

MaAncheNo

Member
Licensed User
Longtime User
Da cui direi che portare Float ad Integer non produca risparmio.

In questo caso non è il risparmio dimensionale che conta, sono entrambi 4 bytes, ma il numero di digits disponibili ed conseguente numero di decimali (precisione della posizione GPS) disponibili nella rappresentazione in un +/- 90.xxxxxx gradi.
Se il Float ha circa 7 digits l'Int ne ha 10 di cui (nel caso di +/- 90 gradi) 9 utilizzabili.
Sempre che non abbia fatto male i conti... :D
 
  • Like
Reactions: udg
Top