|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Dec 2004
Città: Napoli
Messaggi: 342
|
[C] XOR bitwise su double
Salve,
conoscete un modo per usare l'operatore '^', per lo XOR bitwise, su due double? Gli operatori bitwise in C possono essere utlizzati solo con interi, non c'è un modo che permette di riversare i double in un long int o long long int e operare lo XOR? Grazie. A presto.
__________________
Il futuro lo conoscerete quando sarà arrivato, prima di allora dimenticatelo. (Eschilo) |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Mar 2009
Città: Bologna
Messaggi: 1174
|
Non so a cosa ti serva... ma utilizzando cast e puntatori... puoi usare gli operatori bitwise su locazioni di double... attraverso i valori dei puntatori "long long"
Una cosa del genere: Codice:
double a, b, result; long long *aInt = (long long *)&a; long long *bInt = (long long *)&b; long long *rInt = (long long *)&result; a=1.0; b=2.33; *rInt=*aInt^*bInt; printf("%lx, %lx, %lx, %f, %f, %f\n", *aInt, *bInt, *rInt, a, b, result); |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Dec 2004
Città: Napoli
Messaggi: 342
|
Quote:
Se un processore cade posso recuperare i dati effettuano sempre lo xor logico dei dati restanti con quelli salvati. Così Codice:
check = a ^ b; Se perdo il valore di a lo recupero così a = check ^ b; Grazie lo stesso, a presto.
__________________
Il futuro lo conoscerete quando sarà arrivato, prima di allora dimenticatelo. (Eschilo) |
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Mar 2009
Città: Bologna
Messaggi: 1174
|
Certo che, conditio sine qua non affinche' funzioni e' che:
sizeof(long long) == sizeof(double) Altrimenti e' necessario creare una union di tipo adeguato a contenere un double. Nell'esempio c'e' sia il metodo di ieri che la union... che puoi modificarti a seconda dell'esigenza... e funzionano entrambi: Codice:
#include <stdio.h> #include <stdlib.h> typedef union _CNV { double d; long long l; unsigned char c[8]; } CNV; int main(void) { double a, b, result; long long *aInt = (long long *)&a; long long *bInt = (long long *)&b; CNV au, bu; a=1.44; b=2.33; au.d=1.44; bu.d=2.33; printf("sizeof longlong %d, sizeof double %d\n\n", sizeof(long long), sizeof(double)); printf("Stampa variabili:\n"); printf("aInt=%lx, bInt=%lx\na=%f, b=%f\naViaInt=%f bViaInt=%f\n", *aInt, *bInt, a, b, *((double *)aInt), *((double *)bInt)); printf("Stampa Union:\n"); printf("aInt=%lx, bInt=%lx\na=%f, b=%f\naViaC[8]=%f bViaC[8]=%f\n\n", au.l, bu.l, au.d, bu.d, *((double *)au.c), *((double *)bu.c)); printf("ruoto i valori double via xor i valori:\n\n"); *aInt^=*bInt; *bInt^=*aInt; *aInt^=*bInt; au.l^=bu.l; bu.l^=au.l; au.l^=bu.l; printf("Stampa variabili ruotate:\n"); printf("aInt=%lx, bInt=%lx\na=%f, b=%f\naViaInt=%f, bViaInt=%f\n", *aInt, *bInt, a, b, *((double *)aInt), *((double *)bInt)); printf("Stampa Union ruotata:\n"); printf("aInt=%lx, bInt=%lx\na=%f, b=%f\naViaC[8]=%f bViaC[8]=%f\n\n", au.l, bu.l, au.d, bu.d, *((double *)au.c), *((double *)bu.c)); } Codice:
sizeof longlong 8, sizeof double 8 Stampa variabili: aInt=3ff70a3d70a3d70a, bInt=4002a3d70a3d70a4 a=1.440000, b=2.330000 aViaInt=1.440000 bViaInt=2.330000 Stampa Union: aInt=3ff70a3d70a3d70a, bInt=4002a3d70a3d70a4 a=1.440000, b=2.330000 aViaC[8]=1.440000 bViaC[8]=2.330000 ruoto i valori double via xor i valori: Stampa variabili ruotate: aInt=4002a3d70a3d70a4, bInt=3ff70a3d70a3d70a a=2.330000, b=1.440000 aViaInt=2.330000, bViaInt=1.440000 Stampa Union ruotata: aInt=4002a3d70a3d70a4, bInt=3ff70a3d70a3d70a a=2.330000, b=1.440000 aViaC[8]=2.330000 bViaC[8]=1.440000 Nota che stampo i valori double anche col c[8] della union, forzando un cast... nella ultima printf Ultima modifica di BrutPitt : 15-04-2009 alle 10:27. |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Poi non capisco che senso abbia eseguire lo xor di due double. Qual è il tuo vero scopo?
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Mar 2009
Città: Bologna
Messaggi: 1174
|
Quote:
del dato condiviso si salva lo XOR: check = a ^ b; Se "muore" a lo si recupera via: a = check ^ b; Se "muore" b si recupera via: b = a ^ check; Insomma una ridondanza del solo 50% su un'eventuale ripristino dati. Be', l'esempio precedente... con un po' di criterio... lo si puo' fare assolutamente portabile, anche ingorando il tipo di architettura, quanto sia grande un duoble e facendo finta anche che un char non sia per forza un byte: Codice:
#include <stdio.h> #include <stdlib.h> typedef union _CNV { double d; char c[sizeof(double)/sizeof(char)]; } CNV; int main(void) { CNV au, bu; int i; au.d=1.44; bu.d=2.33; printf("a=%f, b=%f\n\n",au.d, bu.d); for(i=0;i<sizeof(double);i+=sizeof(char)) { au.c[i]^=bu.c[i]; bu.c[i]^=au.c[i]; au.c[i]^=bu.c[i]; } printf("Stampa Union ruotata:\n"); printf("a=%f, b=%f\n\n",au.d, bu.d); } Sicuramente non voleva essere la soluzione "assoluta" o "confezionata" al suo problema... ![]() |
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Capito. Rimane comunque valido all'interno della medesima architettura / compilatore.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Dec 2004
Città: Napoli
Messaggi: 342
|
Vi ringrazio per le risposte.
Io cerco una soluzione che sia portabile. L'ultima soluzione lo è?
__________________
Il futuro lo conoscerete quando sarà arrivato, prima di allora dimenticatelo. (Eschilo) |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
No. Qualunque assunzione fai sulla struttura di un double la rende non portabile.
Se, però, rimani all'interno della stessa piattaforma, non ci sono problemi.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Mar 2009
Città: Bologna
Messaggi: 1174
|
Quote:
Con la definizione: typedef union _CNV { double d; char c[sizeof(double)/sizeof(char)]; } CNV; Viene mappato un array di caratteri della dimensione di un double esattamente nell'area di memoria del double... e la dimensione non e' predefinita, ma viene restituita all'atto della compilazione proprio dal compilatore della specifica piattaforma/architettura, grazie all'uso del sizeof... anche nell'inverosimile caso in cui il double non segua lo standard IEEE. E sempre grazie al "sizeof" ogni byte dell'array, e quindi del double, viene elaborato, anche nel caso "strano" in cui un char fosse di 2 o 4 byte: for(i=0;i<sizeof(double);i+=sizeof(char)) { au.c[i]^=bu.c[i]; bu.c[i]^=au.c[i]; au.c[i]^=bu.c[i]; } L'ultimo codice che ho postato e' portabile: basta un qualsiasi compilatore ANSI-C... anzi per le istruzioni che sono presenti basterebbe anche che sia solo conforme allo standard "K&R". Ed e' utilizzabile dai microcontrollori 8/16bit fino alle attuali architetture a 64bit... indipendente dal sistema operativo... sia su processori big-endian che su processori little-endian. Ultima modifica di BrutPitt : 16-04-2009 alle 22:51. |
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Che funzioni sulla STESSA piattaforma l'avevo già detto io.
Ma prova a salvare quei dati e a portarli in un'ALTRA piattaforma, e poi dimmi se ti funziona sempre tutto...
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Dec 2004
Città: Napoli
Messaggi: 342
|
Quote:
su questo penso che tu abbia ragione. I dati se salvati, ad esempio in binario, penso che possano essere utilizzati solo sull'architettura sulla quale sono sono stati creati. Penso che tutte le soluzioni a questo problema siano soggette a questa limitazione, o sbaglio? Grazie, a presto.
__________________
Il futuro lo conoscerete quando sarà arrivato, prima di allora dimenticatelo. (Eschilo) |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Sì, con soluzioni come quella proposta.
Il problema lo si risolve con apposito codice di marshalling o serializzazione che dir si voglia.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
![]() |
![]() |
![]() |
#14 | ||
Senior Member
Iscritto dal: Mar 2009
Città: Bologna
Messaggi: 1174
|
Quote:
Oltretutto avevo precisato che non era mia intenzione dare una soluzione "assoluta" o "confezionata" al suo sistema raid1, ma solo di come fare uno XOR, portabile, sui double... e in tal modo avevo inteso e risposto. Cosa farne dello XOR ottenuto era inteso che doveva essere sua cura, in base alle esigenze che aveva... tant'e' che nell'esempio operavo una semplice rotazione. Per cui, quando ho letto la tua risposta, non pensavo ti riferissi ai dati da salvare/ripristinare ![]() Quote:
Quelli si' sono architettura/S.O. dipendenti anche nelle dimensioni, ma che qui non hai mensionato. I double, in definitiva, appartengono allo standard ANSI/IEEE 754 ed e' uno standard praticamente su tutte le architetture/S.O. che definiscono una "doppia precisione in virgola mobile", in hardware o in emulazione. Ed il ripristino si ridurrebbe ad un ciclo inverso di XOR nel caso in cui l'architettura che subentra differisca nel byte-order (big-endian/little-endian) Piu' complesso e' il ripristino di int, long, long long, etc. nel caso in cui differiscano anche per dimensione. E i bit di stato, indirizzi e quant'altro? Ma stiamo parlando di ripristino di interi processi, di ripristino di un cluster di calcolo distribuito... o di cosa? |
||
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Dec 2004
Città: Napoli
Messaggi: 342
|
Quote:
In pratica, salvo tutti dati su file binari, poi per recuperare i dati leggo i file e faccio la decodifica.
__________________
Il futuro lo conoscerete quando sarà arrivato, prima di allora dimenticatelo. (Eschilo) Ultima modifica di osa : 17-04-2009 alle 16:17. |
|
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Mar 2009
Città: Bologna
Messaggi: 1174
|
MPI... ma non lo potevi dire subito?
![]() In MPI il trasferimento dati tra i cluster viene fatto in modo assolutamente non ambiguo, ed ogni differenza cosi' come l'architettura big/little endian e/o la lunghezza dati e' assolutamente trasparente ai cluster. Pero' ha tipi di dati interni, e devi usare quelli. Nell'esempio precedente... dovresti sostituire "double" con MPI_DOUBLE, e "char" con MPI_CHAR. Mi verrebbe quasi da dire che ho fatto bene a non preoccuparmi di dove finissero i dati... se non fosse che anche l'esempio di XOR e' inutile... ![]() Se non ricordo male MPI_reduce non opera direttamente lo XOR bitwise, anche su MPI_FLOAT e MPI_DUOBLE? |
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Dec 2004
Città: Napoli
Messaggi: 342
|
Quote:
MPI effettua lo xor solo su char ![]() Grazie, a presto.
__________________
Il futuro lo conoscerete quando sarà arrivato, prima di allora dimenticatelo. (Eschilo) |
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Dec 2004
Città: Napoli
Messaggi: 342
|
Ad esempio il seguente codice non funziona:
Codice:
#include <mpi.h> #include <stdio.h> #include <stdlib.h> typedef union _CNV { double d; char c[sizeof(double)/sizeof(MPI_CHAR)]; } CNV; void xorDouble( double *, double *, int *, MPI_Datatype * ); int main( int argc, char **argv ) { int id, size, i, n; MPI_Op MPI_DOUBLE_XOR; double *send, *receive , *rec, *send2; char file[250]; MPI_Init( &argc, &argv ); MPI_Comm_rank( MPI_COMM_WORLD, &id ); MPI_Comm_size( MPI_COMM_WORLD, &size ); n = atoi(argv[1]); send = (double *)calloc(n,sizeof(double)); send2 = (double *)calloc(n,sizeof(double)); receive = (double *)calloc(n,sizeof(double)); rec = (double *)calloc(n,sizeof(double)); // INIZIALIZZO I VETTORI if ( id == 0) { for (i=0; i < n; i++) send[i] = i; } else { for (i=0; i < n; i++) send[i] = 1.0 + i; } MPI_Op_create( (MPI_User_function *)xorDouble, 1, &MPI_DOUBLE_XOR ); MPI_Reduce(send,receive,n,MPI_DOUBLE,MPI_DOUBLE_XOR,0,MPI_COMM_WORLD); if (id == 0) send2 = receive; else send2 = send; /* ADESSO FACCIO L'XOR TRA IL RISULTATO DEL VECCHIO REDUCE E IL DATO DI ORIGINE DEL PROC. 1, DOVREI AVERE IL DATO INIZIALE DEL PROC 0 */ MPI_Reduce(send2,rec,n,MPI_DOUBLE,MPI_DOUBLE_XOR,0,MPI_COMM_WORLD); if ( id == 0) { for (i=0; i < n; i++) printf("%f\n", rec[i]); } MPI_Finalize(); return 0; } 1.000000 inf 1.500000 A presto.
__________________
Il futuro lo conoscerete quando sarà arrivato, prima di allora dimenticatelo. (Eschilo) |
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Quote:
![]()
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:39.