Vlákno názorů k článku Norma IEEE 754 a příbuzní: formáty plovoucí řádové tečky od Pavel Píša - Článek je velice hezký, jen bych chtěl upozornit...

  • Článek je starý, nové názory již nelze přidávat.
  • 31. 5. 2006 15:20

    Pavel Píša (neregistrovaný)
    Článek je velice hezký, jen bych chtěl upozornit na to, že příklad na převod/analýzu bitů formátu single není bezpečně přenositelný na jiné architektury či dokonce kompilátory.

    Norma jazyka C nedefinuje vzestupné či sestupné pořadí položek v bitových polích. Příklad tedy nemusí fungovat na jiných architekturách. Explicitní použití uint32_t, posunů a maskování by tedy bylo správnější.

    Nepamatuji si, že by norma IEEE 754 někde preferovala určitý endianing. Z toho vyplývá, že pořadí položek v paměti při přístupu po bytech též není specifikované. Většinou procesory ukládají single se shodným endianingem jako int32_t. Pro double je to většinou shodné s int64_t. Ovšem existují i komprocesory (například na ARMu), které ukládají obě slova z double v pořadí byte podle své architektury, ale pořadí slov je opačné.

    Nejsou to věci až tak pro obvyklé uživatele PC podstatné, ale pokud pracujete s více architekturami tak jako my, tak je dobré si na to dát pozor a nespoléhat na to, že když to zrovna chodí na PC, bude to chodit i jinde.

    Pro přenositelný kód lze použít hlavičkový soubor "ieee754.h" nebo "ieeefp.h" (NEWLIB). Ten definuje něco jako __BYTE_ORDER a __FLOAT_WORD_ORDER. Dále typy ieee754_float a ieee754_double pro přístup k jednotlivým položkám čísel.
  • 31. 5. 2006 15:38

    Pavel Tišnovský
    Zlatý podporovatel
    Dobrý den,

    máte naprostou pravdu v tom, že ten ukázaný převod mezi bitovými poli a FP hodnotou není přenositelný a to ani při "bytovém" přístupu (viz poslední odstavec této odpovědi). IEEE 754 se tímto nezabývá (už jen proto, že například architektura 68k atd. používá jiný endianing než x86), tam jsou popsány "pouze" formáty a aritmetické/konverzní operace, tj. případy, kdy je hodnota již uložená například v registru (ať už v mikroprocesoru či někde na FPGA či zadrátovaném FPU).

    Jinak indexy bitů, tj. jejich polohy, jak jsou popsané v článku, jsou samozřejmě platné, ale opět až po načtení do registru, "bitový" pohled na paměť může být (a na x86 například je) odlišný.

    Když už jsme u těch norem: měl jsem problémy s překladači Céčka na některých DSPčkách, protože ty chápaly byte jako 32bitů, což se kupodivu shoduje s definicí uvedenou v normě ANSI C (a možná také v ISO C, tu však nemám). Proto pozor, někdy může platit třeba toto:

    sizeof(char) == sizeof(short) == sizeof(int) ==
    sizeof(long) == sizeof(float) == sizeof(double) == 1

    A tu jedničku nutno chápati ne jako 8 bitů ale 32 bitů (popř. na jiných DSP či CPU jinou hodnotu). Problémy jsou zejména s mallocem() a také při komunikaci s PC (měli jsme to DSP na vlastním PCI bastlu).
  • 31. 5. 2006 20:35

    Pavel Píša (neregistrovaný)
    To je všechno v pořádku. C je totiž jazyk přenositelný a snaží se typy int a char mapovat tak aby se s nimi pracovalo nativně a co nejrychleji. Někdy z toho ale člověk šediví když potřebuje pevné délky. Norma C99 naštěstí konečne po 30 letech zavádí do C typy int32_t atd.

    Mám takový pocit, že C99 již vyžaduje/doporučuje char osmibitový, což je svým způsobem škoda.

    Indexy jsou sice v IEEE 754 definovány, ale v zásadě se to týká pouze registrů FPU. Po načtení čísla do celočíselných typů/registrů tedy nelze s jistotou nic říct. Viz ten ARM s VAX (mixed) endianingem.

    Zdravím a těším se na další článek. Píšete to dobře a těšilo by mě, kdyby to naši studenti četli a uměli.