Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Baby Reindeer - 2024

Hotii voteaza hoti?!

Camera video masina

Zilele emailului din gospodaria n...
 Best gaming laptop?

Humane (2024)

Recomandare casti 100-150 lei

Schimbare bec far VW Touran 1T3
 Plata impozit PF

Ce parere aveti de viteza/ modul ...

Love Lies Bleeding - 2024

Cum sterg mails din Promotions
 Vanzare cumparare fara transfer b...

Receptie ciudata, in functie de t...

Donez medicamente renale ptr pisica

Ce componenta e asta si ce ziceti...
 

Convertire array integer de count=10 la count=3

- - - - -
  • Please log in to reply
16 replies to this topic

#1
GabyF

GabyF

    Junior Member

  • Grup: Members
  • Posts: 235
  • Înscris: 27.09.2006
Am un array integer de count=10 care poate avea doar maximum 141 valori, deci de la 0 la 140
Vreau sa introduc datele in alt array integer de count=3 care poate avea 16777217 valori, deci de la 0 la 16777216

Solutia mea este sa folosesc numerele in baza egala cu maximul de valori permise, asa ca:

#define XDOUBLE 6
double arrayToNumber(int *arr_values, int base, int nr_values) {
  if (nr_values>2) {
	nr_values--;
	return double(arrayToNumber(arr_values, base, nr_values)*base+arr_values[nr_values]);
  }
  else
#ifdef XDOUBLE 
	return double(arr_values[0]*base+arr_values[1])/pow(10.,XDOUBLE);
#else
	return double(arr_values[0]*base+arr_values[1]);
#endif
}
void numberToArray(double all_value, int base, int nr_values, int *&arr) {
for (int i=nr_values-1; i>=0; i--) {
#ifdef XDOUBLE 
	arr[i]=(int)fmod(all_value*pow(10.,XDOUBLE),(double)base);
#else
	arr[i]=(int)fmod(all_value,(double)base);
#endif
	all_value=floor(all_value/base);
}
}
void arrayToArray(int *arr1, int base, int nr_values1, int base2, int nr_values2, int *&arr2) {
numberToArray(arrayToNumber(arr1, base, nr_values1), base2, nr_values2, arr2);
}
#define COUNT 10
#define COUNT2 3
int tmp[]={140,12,13,1,13,1,3,13,1,3}, *arr, *arr2, base=141, base2=16777216;
arr=new int[COUNT]; arr2=new int[COUNT2];
for (int i=0; i<COUNT; i++) {
  arr[i]=tmp[i];
}
Debug("arrayToNumber, %f",arrayToNumber(arr, base, COUNT));
arrayToArray(arr, base, COUNT, base2, COUNT2, arr2);
for (int i=0; i<COUNT2; i++) {
  Debug("arr2 %d, %d",i,arr2[i]);
}
arrayToArray(arr2, base2, COUNT2, base, COUNT, arr);
for (int i=0; i<COUNT; i++) {
  Debug("arr= %d, %d",i,arr[i]);
}


Problema e ca acel numar intermediar all_value este foarte mare.

Codul merge la valori mai mici, de ex COUNT 7 si COUNT2 3 fara sa definesc XDOUBLE, dar in acest exemplu nu.

Edited by GabyF, 26 January 2023 - 12:27.


#2
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,239
  • Înscris: 24.02.2007
Nu ai de ce sa folosesti double/float aici. Face mai mult rau decat bine.

#3
MarianG

MarianG

    be that as it may

  • Grup: Moderators
  • Posts: 31,445
  • Înscris: 10.08.2005

Quote

Am un array integer de count=10 care poate avea doar maximum 141 valori, deci de la 0 la 140
de ce vrei sa lucrezi in baza 141 ?

#4
GabyF

GabyF

    Junior Member

  • Grup: Members
  • Posts: 235
  • Înscris: 27.09.2006
Pentru ca datele din primul array au maxim 140. Specific ca trebuie sa mearga si pe sistem 32biti

View Postdani.user, on 26 ianuarie 2023 - 12:26, said:

Nu ai de ce sa folosesti double/float aici. Face mai mult rau decat bine.

Ai tu alta solutie?

Edited by GabyF, 26 January 2023 - 12:35.


#5
MarianG

MarianG

    be that as it may

  • Grup: Moderators
  • Posts: 31,445
  • Înscris: 10.08.2005
acum sirul asta de lungime 3, cu 16777217 de valori maxime imi suna a fi de 2^(3*8)

tip_de_date sir_fara_nume[3];  // 3 elemente intregi;  16777216 (2^24) total variatii --> intreg de 8 biti;
tip_de_date alt_sir_fara_nume[10] ; // 10 elemente intregi ; 141 (2^8)total variatii --> intreg de 0.8 biti ?

Edited by MarianG, 26 January 2023 - 12:51.


#6
GabyF

GabyF

    Junior Member

  • Grup: Members
  • Posts: 235
  • Înscris: 27.09.2006
Da, si la ce ajuta? Important este sa mearga ca principiu, poate fi si 15000000... important este ca array-ul secund sa acopere capacitatea de date necesara din primul array.

Edited by GabyF, 26 January 2023 - 12:56.


#7
MarianG

MarianG

    be that as it may

  • Grup: Moderators
  • Posts: 31,445
  • Înscris: 10.08.2005
Eu nu inteleg ce reprezinta exact sirul tau de numere.
Cine te limiteaza sa ai valori mai mari de 141 ?
Valoarea fiecarui element este maxim 141 sau totalul de combinatii dintre cele 10 elemente este 141?

Te ajuta sa-ti creezi o structura de date, pe ce dimensiuni ai nevoie

Edited by MarianG, 26 January 2023 - 12:59.


#8
GabyF

GabyF

    Junior Member

  • Grup: Members
  • Posts: 235
  • Înscris: 27.09.2006
Valoarea este maxim 141 , am spus. Important este sa mearga functia, o s-o folosesc la mai multe, nu conteaza de ce e limitat la 141, este bine, daca nu era limitarea nu se putea compacta array-ul.

Reformulez, deci e vorba de a compacta un array la un alt array cu count mai mic dar cu un maxim mai mare pentru salvare date in format mai redus.

Ar trebui sa mearga pentru ca 141^10 < 16777217^3

Edited by GabyF, 26 January 2023 - 13:11.


#9
MarianG

MarianG

    be that as it may

  • Grup: Moderators
  • Posts: 31,445
  • Înscris: 10.08.2005
141^10 3,105,926,159,393,528,563,401
16777216^03 4,722,366,482,869,645,213,696

doar ca ambele depasesc 64 de biti

Edited by MarianG, 26 January 2023 - 13:27.


#10
wertyck

wertyck

    Guru Member

  • Grup: Senior Members
  • Posts: 13,621
  • Înscris: 13.03.2005
Una dintre solutii ar fi sa folosesti tipul de date "long double" in loc de "double" pentru a stoca numarul intermediar, care ofera o precizie mai mare. De asemenea, ar trebui sa verifici daca "XDOUBLE" este necesar si sa il elimini daca nu este necesar.

O alta solutie ar fi sa eviti sa folosesti un numar intermediar si sa lucrezi direct cu array-urile de numere intregi, inlocuind operatiile de inmultire si impartire cu operatii de shiftare si bitwise pentru a face conversia intre baze

#11
GabyF

GabyF

    Junior Member

  • Grup: Members
  • Posts: 235
  • Înscris: 27.09.2006
As vrea sa mearga si pe 32biti dupa cum am zis. Este necesar sa folosesc XDOUBLE pentru decimalele alocate pt double , avem 1.79769e+308 , suficient as zice. Nu-mi dau seama cum sa folosesc aici bitwise

Am gasit o eroare evidenta dar tot nu merge:

void numberToArray(double all_value, int base, int nr_values, int *&arr) {
for (int i=nr_values-1; i>=0; i--) {
#ifdef XDOUBLE
arr[i]=(int)fmod(all_value*pow(10.,XDOUBLE),(double)base);
all_value=all_value/base;
#else
arr[i]=(int)fmod(all_value,(double)base);
all_value=floor(all_value/base);
#endif
}
}


Edited by GabyF, 26 January 2023 - 14:22.


#12
Pafarist

Pafarist

    Junior Member

  • Grup: Members
  • Posts: 189
  • Înscris: 01.06.2009
Salut!
Cred că @wertyck a vrut să sugereze ceva în sensul prezentat mai jos.
Pentru Array2 poți folosi elemente de 32 bit (de exemplu, unsigned int).
Operațiile pe biți necesare la popularea Array2 sunt prezentate în tabel, în coloana Value.
Pentru a le extrage, folosești operațiile inverse (shift dreapta + un AND cu o mască adecvată).

Attached Files



#13
GabyF

GabyF

    Junior Member

  • Grup: Members
  • Posts: 235
  • Înscris: 27.09.2006
am inteles ideea dar practic... ?

#14
Pafarist

Pafarist

    Junior Member

  • Grup: Members
  • Posts: 189
  • Înscris: 01.06.2009
Practic, dacă ai:
char Array1[10]; 
unsigned int Array2[3];


atunci vei putea compacta elementele din Array1 în Array1 folosind:
Array2[0] = Array1[3]<<24 + Array1[2]<<16 + Array1[1]<<8 + Array1[0];
Array2[1] = Array1[7]<<24 + Array1[6]<<16 + Array1[5]<<8 + Array1[4];
Array2[2] = Array1[9]<<8 + Array1[8];

Codul se poate optimiza iterativ pentru Count1 și Count2 variabile, cu restricția Count1<=4*Count2.
Baftă!

#15
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,239
  • Înscris: 24.02.2007
Exista biblioteci pentru lucrul cu valori intregi oricat de mari, cum ar fi boost::multiprecision. Implementarea uneia de la 0 e un exercitiu fain.

unsigned char input[10] = {140, 140, 140, 140, 140, 140, 140, 140, 140, 140};
unsigned char output[9] = {0};

boost::multiprecision::cpp_int v;
for (int x : input)
{
	v = v * 141 + x;
}
int i = 0;
while (v > 0)
{
	output[i++] = static_cast<unsigned char>(v % 256);
	v /= 256;
}


Exercitiul asta insa e ciudat. 10 bytes poti compacta la 9... cam mare bataia de cap pentru castiguri marunte.

#16
MarianG

MarianG

    be that as it may

  • Grup: Moderators
  • Posts: 31,445
  • Înscris: 10.08.2005

View PostPafarist, on 26 ianuarie 2023 - 19:54, said:

Practic, dacă ai:
char Array1[10];
unsigned int Array2[3];


atunci vei putea compacta elementele din Array1 în Array1 folosind:
Array2[0] = Array1[3]<<24 + Array1[2]<<16 + Array1[1]<<8 + Array1[0];
Array2[1] = Array1[7]<<24 + Array1[6]<<16 + Array1[5]<<8 + Array1[4];
Array2[2] = Array1[9]<<8 + Array1[8];

Codul se poate optimiza iterativ pentru Count1 și Count2 variabile, cu restricția Count1<=4*Count2.
Baftă!
de la 10 octeti la 12 octeti
Array2[2] = 0<<24 + 0<<16 + Array1[9]<<8 + Array1[8];

Edited by MarianG, 26 January 2023 - 23:22.


#17
GabyF

GabyF

    Junior Member

  • Grup: Members
  • Posts: 235
  • Înscris: 27.09.2006
Mersi!

Anunturi

Bun venit pe Forumul Softpedia!

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate