abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 06:00 | IT novinky

Na Indiegogo byla spuštěna kampaň na podporu chytrého telefonu a kapesního počítače Astro Slide 5G Transformer od společnosti Planet Computers. Požadovaná částka 180 000 eur byla vybrána během 4 hodin. Stejně jako u předchozích zařízení Gemini PDA a Cosmo Communicator od této společnosti je slíbená podpora Linuxu.

Ladislav Hagara | Komentářů: 9
včera 19:22 | Zajímavý software

CryptPad je svobodný online kancelářský balík. Zdrojové kódy jsou k dispozici na GitHubu pod licencí AGPL-3.0. Oficiální instance nově nabízí 1 GB prostoru. Mozilla Foundation tento týden věnovala projektu 10 000 $.

Ladislav Hagara | Komentářů: 2
včera 18:22 | Nová verze

Byla vydána finální beta verze Ubuntu 20.04 LTS s kódovým názvem Focal Fossa. Přehled novinek v poznámkách k vydání. Dle plánu by Ubuntu 20.04 mělo vyjít 23. dubna 2020.

Ladislav Hagara | Komentářů: 4
včera 17:22 | Nová verze

Vyšel XCP-ng 8.1 (seznam změn), alternativní sestavení Citrix Hypervisor (dříve XenServer), tedy serverová distribuce hypervizoru Xen (4.13), toolstacku XAPI a systému CentOS v privilegované doméně. XCP-ng na rozdíl od bezplatné verze Citrix Hypervisoru nemá četná omezení funkcionality, vývojáři ale nabízejí i komerční podporu. Novinkou (zatím) pouze v XCP-ng je možnost zálohovat VM včetně aktuálního stavu jejich paměti; funkce je integrována také v administračním nástroji Xen Orchestra.

Fluttershy, yay! | Komentářů: 0
2.4. 17:55 | Nová verze

Byl vydán LineageOS ve verzi 17.1. LineageOS (Wikipedie) je svobodný operační systém pro chytré telefony, tablety a set-top boxy založený na Androidu. Jedná se o nástupce CyanogenModu. LineageOS 17.1 je založený na Androidu 10.

Ladislav Hagara | Komentářů: 9
2.4. 17:22 | Zajímavý projekt

Lukasz Erecinski na blogu Pine64 oznámil možnost předobjednání telefonu PinePhone v edici UBports Community Edition. Telefon bude mít speciální kryt s logem a nápisem UBports Edition. Základní deska bude podle nového schématu (v1.2) vylepšená podle zpětné vazby od majitelů BraveHeart edice. Bude mít FCC i CE certifikace.

joejoe | Komentářů: 3
2.4. 15:33 | IT novinky

Společnost Cloudflare před dvěma lety spustila DNS resolver 1.1.1.1. Včera spustila 1.1.1.1 pro rodiny aneb nové resolvery 1.1.1.2 (2606:4700:4700::1112) a 1.1.1.3 (2606:4700:4700::1113) blokující stránky s malwarem a obsahem pro dospělé. Dnes se omluvila, že nechtěně blokovala také LGBTQIA+ stránky.

Ladislav Hagara | Komentářů: 36
2.4. 14:55 | Nová verze

Společnost Red Hat oznámila vydání Red Hat Enterprise Linuxu 7.8, který přináší vedle nových vlastností a oprav chyb také aktualizaci ovladačů a předběžné ukázky budoucích technologií. Podrobnosti v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
2.4. 14:33 | Nová verze

V pondělí vyšel Linux 5.6. Dnes vyšla jeho 2. opravná verze 5.6.2 (git). Opravena byla mimo jiné diskutovaná chyba v ovladači iwlwifi.

Ladislav Hagara | Komentářů: 0
1.4. 19:55 | Nová verze

Po dvou letech od vydání verze 3.0 byla vydána nová major verze 4.0 nástrojů LXC, LXD a LXCFS pro kontejnerovou virtualizaci LXC (LinuX Containers). Jedná se o verzi s dlouhodobou podporou (LTS). Ta končí v červnu 2025. Přehled novinek v jednotlivých oznámeních o vydání: LXC, LXD a LXCFS.

Ladislav Hagara | Komentářů: 3
Chodíte do práce?
 (26%)
 (2%)
 (5%)
 (2%)
 (48%)
 (13%)
 (4%)
Celkem 104 hlasů
 Komentářů: 4, poslední 2.4. 14:20
Rozcestník

www.AutoDoc.Cz

Dotaz: Změna typu existujících integerů v poli

25.2. 09:33 Jirka | skóre: 24
Změna typu existujících integerů v poli
Přečteno: 429×
Zdravím všechny,
Mám např. uint32_t array[10000000] s existujícími obrazovými daty, se kterými provedu nějaké výpočty, nakonec všechny prvky v poli odmocním, takže se vejdou do 16bit prostoru a také je chci uložit pomocí fwrite jako 16bit raw.

Dá se to nějak provést bez tvorby ještě jednoho pole uint16_t o stejné velikosti? Ideálně změnit typ už vytvořeného pole, tj. na stejných adresách se zachováním hodnot a to pak uložit. Nebo přesvědčit fwrite, aby ukládal jen posledních 16bitů z každého prvku a to ostatní ignoroval (tedy ani nevyplňoval nulama). Raspberry jedno velké pole ustojí, se dvěma už má občas problém.
Díky.
Dokud to funguje, nešťourej se v tom!...

Řešení dotazu:


Odpovědi

Řešení 1× (Jirka (tazatel))
25.2. 09:56 finn | skóre: 43 | blog: finnlandia | 49° 44´/13° 22´
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Vytvořit si pomocné pole uint16_t temparr[] a ve smyčce do něj ukládat části původního pole a ty zapisovat?

#define TA_LEN 1000;

static inline void zkonvertuj_dalsi_cast_pole(uint16_ * temparr, uint32_t * array, size_t index, size_t TA_LEN)
{
  ...
}

void foo(void)
{
  FILE file;
  size_t index = 0;
  uint16_t temparr[TA_LEN];
  ...
  while(pole_jeste_neni_zpracovano)
  {
    zkonvertuj_dalsi_cast_pole(temparr, array, index, TA_LEN);
    fwrite(temparr, sizeof(temparr), 1, file);
    index += TA_LEN;
  }
  ...
}
V příkladu samozřejmě není ošetřená případná chyba fwrite() nebo stav kdy TA_LEN není soudělné s počtem prvků pole array[]
Užívej dne – možná je tvůj poslední.
25.2. 10:19 Jirka | skóre: 24
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Díky, dobrej nápad! :-)
Přesná velikost pole je [12216864], to je dělitelné 32, takže bude stačit pole uint16_t [381777], to už by mělo projít.
Dokud to funguje, nešťourej se v tom!...
25.2. 12:48 debian+
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Co tak bez dalsieho pomocneho ukladat?
uint32_t array[10000000];
uint32_t *index;
size_t i;

for(index=array, i=0; i <= 10000000; i++, index++)
{
	fwrite(*((uint16_t) index), sizefof(uint16_t), 1, FD);
}

/* este raz a citatelnejsie */
uint32_t array[10000000];
uint32_t *index;
uint16_t u16;
size_t i;

for(index=array, i=0; i <= 10000000; i++, index++)
{
	u16=(uint16_t) *index;
	fwrite(u16, sizefof(uint16_t), 1, FD);
}
Ono takto definovane by sa vo funkcie malo vytvarat na zasobniku. A to nemusi az tak v tentokrat u Andruido prospievat. Nechces pripadne allokovat pre beh programu tuto pamet cez malloc.
25.2. 13:00 debian+
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Na druhej strane, preco ukladat fwrite po 1 bajte, ked sa da naraz? Hm, to nove pomocne pole sa potom zide. Alebo to mozes skonvertovat v tom istom poli.
25.2. 14:03 finn | skóre: 43 | blog: finnlandia | 49° 44´/13° 22´
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Tipuju, že tohle bude násobně až řádově pomalejší oproti zápisu po blocích.
Užívej dne – možná je tvůj poslední.
25.2. 19:51 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli

Ůůůfff. Tohle ale mlčky předpokládá Little Endian, kde se dá jenom tak přetypovat uint32_t* na uint16_t* a ty dolní byty tam budou. Na Big Endian tam bude všude nula (horní byty).

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
25.2. 19:53 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli

Ne, beru zpět, neumím číst. Pointer se tady nepřetypuje, takže je to OK.

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
25.2. 19:45 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Dá se to nějak provést bez tvorby ještě jednoho pole uint16_t o stejné velikosti?

Ano. Například nějak tahle (convert_in_place(...)):

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

static const size_t SIZE = 100000;
typedef uint16_t narrow_array_t[SIZE];
typedef uint32_t wide_array_t[SIZE];
typedef uint16_t (*narrow_array_ptr)[SIZE];
typedef uint32_t (*wide_array_ptr)[SIZE];

////////////////////////////////////////////////////////////////////////////////
static narrow_array_ptr convert_in_place(const wide_array_ptr wide_array) {
  const uint32_t *source = *wide_array;
  uint16_t *dest = (uint16_t*)source;
  const uint16_t *const end = dest + SIZE;
  while (dest < end) *dest++ = *source++;
  return realloc(wide_array, sizeof(narrow_array_t));  // free extra memory
  // return (narrow_array_ptr)wide_array;              // keep extra memory
}
////////////////////////////////////////////////////////////////////////////////

static int dump_array_to_file(const char *const file_name,
                              const narrow_array_ptr narrow_array) {
  const int output = open(file_name,
                          O_WRONLY | O_CREAT | O_TRUNC,
                          S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
  if (output == -1) {
    fputs(strerror(errno), stderr);
    return EXIT_FAILURE;
  }
  int result = EXIT_SUCCESS;
  size_t to_write = sizeof(narrow_array_t);
  uint8_t *buffer = (uint8_t*)narrow_array;
  while (to_write) {
    const ssize_t written = write(output, buffer, to_write);
    if (written == -1) {
      result = EXIT_FAILURE;
      fputs(strerror(errno), stderr);
      break;
    }
    buffer += written;
    to_write -= written;
  }
  if (close(output) == -1) {
    fputs(strerror(errno), stderr);
    return EXIT_FAILURE;
  }
  return result;
}

int main() {
  // Allocate and populate an array of 32-bit integers.
  uint32_t (*const wide_array)[SIZE] = malloc(sizeof(wide_array_t));
  if (!wide_array) {
    fputs(strerror(errno), stderr);
    return EXIT_FAILURE;
  }
  for (size_t i = 0; i < SIZE; ++i) (*wide_array)[i] = i % 16384;

  // Compact 32-bit integers into 16-bit integers in-place.
  uint16_t (*const narrow_array)[SIZE] = convert_in_place(wide_array);
  
  // Write compacted array to standard output, just for fun.
  const uint16_t *const end = *narrow_array + SIZE;
  for (uint16_t *number = *narrow_array; number < end; ++number)
    printf("%d, ", *number);  // unchecked!
  putchar('\n');              // unchecked!

  // Write the compacted array into a binary file.
  int result = dump_array_to_file("/tmp/output", narrow_array);
  
  free(narrow_array);
  return result;
}

Pokud se nepletu, tento^^^ kód nezávisí na endianness, protože nedělá žádné podivné bitové operace. Tedy na BE vyrobí binární soubor v BE, na LE vyrobí binární soubor v LE. (A pokud se pletu, hned se mi bude někdo posmívat, takže dobře mi tak.)

Nebo přesvědčit fwrite, aby ukládal jen posledních 16bitů z každého prvku a to ostatní ignoroval (tedy ani nevyplňoval nulama).

Ano, tohle by taky šlo, ale musel by se ten fwrite() (nebo write()) volat SIZE-krát, vždycky na ty 2 byty, což by bylo celkem ošklivé a navíc by to bylo závislé na endianness, tj. muselo by se podle LE/BE správně určit, které 2 byty vypsat.

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
25.2. 20:44 rastos | skóre: 61 | blog: rastos
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Ergo
uint16_t *tmp=(uint16_t*)array;
for (i=0;i<10000000;i++,tmp++)
  *tmp=array[i];
fwrite(array,10000000,sizeof(uint16_t),FD);
Načo si tam písal tých ostatných 76 riadkov?
25.2. 21:14 Jirka | skóre: 24
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Tak díky všem, hoši, to by stačilo, už to zbytečně komplikujete. :-D
Dokud to funguje, nešťourej se v tom!...
25.2. 21:37 debian+
Rozbalit Rozbalit vše Re: Změna typu existujících integerů v poli
Bud rad, ze sme nezacali pisat v ASM.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.