Program pakujący inty do uint64_t i wypisujący je błąd kompilacji.

0

Firma telekomunikacyjna przechowuje dane dotyczące jednej rozmowy w jednej 64-bitowej zmiennej typu unsigned long long (albo lepiej, uint64_t) w której zakodowane są
1.(caller): liczba 17 bitowa, czyli z zakresu
2. (caller_zone): liczba 7 bitowa
3. (callee): liczba 17 bitowa;
4. (callee_zone): liczba 7 bitowa;
5. (duration): liczba 13 bitowa,
6. (tariff): liczba 3 bitowa, czyli z zakresu
Funkcje ma pobrać sześć liczb opisanych wcześniej (jako liczby typu int) i upakować wszystkie do jednej liczby typu uint64_t;
info drukuje informacje o pojedynczej rozmowie przekazane w jednej liczbie typu uint64_t((info korzystając tylko z podstawowej biblioteki iostream).

Napisałem taki wynalazek szukając w google podpowiedzi

#include <iostream>

using namespace std;
void info();
uint64_t eco1(int, int, int, int, int, int);

class encode
{   //deklaruje ile bitów
	struct bits {
		uint64_t caller : 17;
		uint64_t callee : 17;
		uint64_t duration : 13;
		uint64_t caller_zone : 7;
		uint64_t callee_zone : 7;
		uint64_t tariff : 3;
	};	uint_least64_t whole;
		 
public:
	//funkcja pobierająca inty zmienia na uint64_t i zwraca do zmiennych globalnych
	uint64_t eco1(int caller, int caller_zone,
				  int callee, int callee_zone,
				  int duration, int tariff)
	{
		caller      = (uint64_t)caller;
		caller_zone = (uint64_t)caller_zone;
		callee      = (uint64_t)callee ;
		callee_zone = (uint64_t)callee_zone;
		duration    = (uint64_t)duration;
		tariff      = (uint64_t)tariff;
		uint64_t bits;
		bits = caller | caller_zone | callee | callee_zone | duration | tariff; // pakuje przerobione inty do struktury
		
		
	}
	void info() //wypisuje na ekranie (wypisywanie tylko przy urzyciu biblioteki iostream)
	{
		uint64_t caller, caller_zone, callee, callee_zone, duration, tariff;

		cout << "Caller:       " << caller      << endl;
		cout << "Caller_zone : " << caller_zone << endl;
		cout << "Callee :      " << callee      << endl;
		cout << "Callee_zone : " << callee_zone << endl;
		cout << "Duration :    " << duration    << endl;
		cout << "Tariff :      " << tariff      << endl;
	}


};


int main()
{
	info(eco1(130999, 101, 7777, 99, 7000, 6)); //blad za duzo argumentow w wywolaniu funkcji
	uint64_t bits;
	eco1(130999, 101, 7777, 99, 7000, 6);//blad za duzo argumentow w wywolaniu funkcji
	info(bits);
	system("pause");
	return 0;
}
 // samo info ma błąd "info": nie przyjmuje 1 argumentów

Wyskakują mi błędy w kompilacji tylko ich nie rozumiem zwłaszcza tego z zbyt durzą ilością argómentów kiedy mam podanych 6 czyli tyle ille powinienem ;[

0
   //funkcja pobierająca inty zmienia na uint64_t i zwraca do zmiennych globalnych
   uint64_t eco1(int caller, int caller_zone,
                 int callee, int callee_zone,
                 int duration, int tariff)
   {
       caller      = (uint64_t)caller;

Do żadnych zmiennych globalnych nic tu nie przypisujesz. Przypisujsz do parametrów powyżej (które działają tu jak zmienne lokalne). Konwersja do uint64_t idzie zupełnie na marne (choć i tak nie jest potrzebna).

   info(eco1(130999, 101, 7777, 99, 7000, 6)); //blad za duzo argumentow w wywolaniu funkcji

Funkcja into u ciebie nie przyjmuje żadnego parametru, a podajesz jeden - czyli za dużo.

0
Azarien napisał(a):
   //funkcja pobierająca inty zmienia na uint64_t i zwraca do zmiennych globalnych
   uint64_t eco1(int caller, int caller_zone,
                 int callee, int callee_zone,
                 int duration, int tariff)
   {
       caller      = (uint64_t)caller;

Do żadnych zmiennych globalnych nic tu nie przypisujesz. Przypisujsz do parametrów powyżej (które działają tu jak zmienne lokalne). Konwersja do uint64_t idzie zupełnie na marne (choć i tak nie jest potrzebna).

   info(eco1(130999, 101, 7777, 99, 7000, 6)); //blad za duzo argumentow w wywolaniu funkcji

Funkcja into u ciebie nie przyjmuje żadnego parametru, a podajesz jeden - czyli za dużo.

Nie usunąłem komentarza, funkcja nie może mi zwracać do zmiennych globalnych, tylko do jednego uint64_t eco1,
a później przy użyciu void info ma wypisać te dane. Poprawiłem kod i coś jest nie tak z moim u intem chyba bo dostaje błąd:|

Błąd (aktywny) E0167 argument typu "uint64_t (*)(int, int, int, int, int, int)" jest niezgodny z parametrem typu "uint64_t" 59 info(eco1);

#include <iostream>

using namespace std;
void info(uint64_t);
uint64_t eco1(int, int, int, int, int, int);

class encode
{   //deklaruje ile bitów
	struct bits {
		uint64_t caller : 17;
		uint64_t callee : 17;
		uint64_t duration : 13;
		uint64_t caller_zone : 7;
		uint64_t callee_zone : 7;
		uint64_t tariff : 3;
	};	uint_least64_t whole;
		 
public:
	//funkcja pobierająca inty zmienia na uint64_t 
	uint64_t eco1(int caller, int caller_zone,
				  int callee, int callee_zone,
				  int duration, int tariff)
	{
		caller      = (uint64_t)caller;
		caller_zone = (uint64_t)caller_zone;
		callee      = (uint64_t)callee ;
		callee_zone = (uint64_t)callee_zone;
		duration    = (uint64_t)duration;
		tariff      = (uint64_t)tariff;
		uint64_t bits;
		bits = caller | caller_zone | callee | callee_zone | duration | tariff; // pakuje przerobione inty do struktury
		
		uint64_t eco1 = bits;
		return eco1;

		
	}
	void info(uint64_t) //wypisuje na ekranie (wypisywanie tylko przy urzyciu biblioteki iostream)
	{
		uint64_t *caller, *caller_zone, *callee, *callee_zone, *duration, *tariff;

		cout << "Caller:       " << caller      << endl;
		cout << "Caller_zone : " << caller_zone << endl;
		cout << "Callee :      " << callee      << endl;
		cout << "Callee_zone : " << callee_zone << endl;
		cout << "Duration :    " << duration    << endl;
		cout << "Tariff :      " << tariff      << endl;
	}


};


int main()
{
	info(eco1(130999, 101, 7777, 99, 7000, 6)); 
	
	uint64_t bits;

	eco1(130999, 101, 7777, 99, 7000, 6);
	info(eco1);  //argument typu "uint64_t (*)(int, int, int, int, int, int)" jest
                           //niezgodny z parametrem typu "uint64_t" więc chyba zle pakuje do inta ;[
	system("pause");
	return 0;
}


0

Wiesz że pola bitowe nie dają gwarancji kolejności ułożenia (big/little-endian) ani upakowania struktury? Ze względu na przenośność jednak użył bym tradycyjnego przesunięcia bitowego i masek.

0
Mokrowski napisał(a):

Wiesz że pola bitowe nie dają gwarancji kolejności ułożenia (big/little-endian) ani upakowania struktury? Ze względu na przenośność jednak użył bym tradycyjnego przesunięcia bitowego i masek.

Ja na razie wiem że nic nie wiem :P to jest mój pierwszy program ze struktura wcześniej miałem proste układania do tabeli i użycia odnośników do układania(tak w ramach ciekawości się doszkalam z C++).
Mi póki co trzeba paluszkiem pokazać co nie tak robię i jak to mogę poprawić ( ewentualnie czym )

0

Hmm.... No to masz "kod w trybie edukacyjnym". Wystarczy zauważyć że maska bitowa wartości to np. dla 17 bitów ((1 << 17) - 1) a przesunięcie bitowe to suma poprzednich.
Niemniej jednak pomimo że IMHO napisałem przejrzyście (łamiąc delikatnie DRY dla celów umieszczenia struktury w 1 funkcji), będziesz miał wiele pytań:

#include <iostream>
#include <utility>

class encode {
public:
    static uint64_t eco1(int caller, int caller_zone, int callee, int callee_zone,
            int duration, int tariff) {

        std::pair<int, int> values_table[] = {
            { caller, 17 },
            { caller_zone, 7 },
            { callee, 17 }, 
            { callee_zone, 7 },
            { duration, 13 },
            { tariff, 3 }
        };

        int mask{};
        uint64_t value{};
        for(auto& pr : values_table) {
            value |= (static_cast<uint64_t>(pr.first) & ((1 << pr.second) - 1)) << mask;
            mask += pr.second;
        }

        return value;
    }

    static void info(uint64_t value) {
        std::pair<const char *, int> values_table[] = {
            { "Caller", 17 },
            { "Caller_zone", 7 },
            { "Calle", 17 },
            { "Calle_zone", 7 },
            { "Duration", 13 },
            { "Tariff", 3 }
        };

        for(const auto& pr: values_table) {
            std::cout << pr.first << ": " << std::dec
                << static_cast<int>((value & ((1 << pr.second) - 1))) << '\n';
            value >>= pr.second;
        }
    }
};

int main() {
    auto value = encode::eco1(130999, 101, 7777, 9, 7000, 6);
    std::cout << std::hex << value << std::endl;
    encode::info(value);
}
0

WOW dzięki wielkie za kod i za cierpliwość do noobka mnie ;] teraz to na spokojnie oblukać muszę =D

1 użytkowników online, w tym zalogowanych: 0, gości: 1