IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Caster
Člen
Avatar
Caster:7.3.2020 0:12

Převést HEX číslo (4 byte) na decimální v ASCII tvaru.

Zkusil jsem:

#include <iostream>

char ASCIIdec[9];
unsigned __int32 Latitude = 0x1DD82DB4; // 500706740 (dec)

void ASde(unsigned __int32 HexVal) {
        int flag = 0;                           // Potlačení nevýznamných 0 zleva (' ')
        int  exp = 8;
        int cislice;
        unsigned __int32 pom;
        unsigned __int32 cislo = HexVal;
        char cifra;
        for (int i = 8; i > 0; i--) {
                cislice = (cislo / 10 ^ exp);
                cifra = ' ';
                if (cislice = 0 && (flag = 0)) {
                        ASCIIdec[8 - i] = ' ';
                        cislo = cislo - cislice * 10 ^ exp;
                }
                else {
                        flag = 1;
                        ASCIIdec[8 - i] = cifra;
                        cislo = cislo - cislice * 10 ^ exp;
                }
        }
}

int main()
{
        ASde(Latitude);

        return 0;
}

Chci docílit: Nefunguje získání první číslice (5) dělením 108, dává 2.

 
Odpovědět
7.3.2020 0:12
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:7.3.2020 1:37
#define _CRT_SECURE_NO_WARNINGS
#include <cstdlib>

int main(){
   unsigned _int32 Latitude = 0x1DD82DB4 // 500706740 (dec)
   char ASCIIdec[20];

   _itoa(Latitude, ASCIIdec, 10);
   return 0;
}
Nahoru Odpovědět
7.3.2020 1:37
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:7.3.2020 2:27

Díky, kód potřebuji pro ATtiny202 MCU, který má jen 2 kB, nemohu použít knihovnu s funkcí _itoa.

 
Nahoru Odpovědět
7.3.2020 2:27
Avatar
zitekv
Člen
Avatar
Odpovídá na Caster
zitekv:7.3.2020 8:32

Ty používáš postup převodu z desítkové soustavy...
Pro převod z jiné do desítkové je to trochu jinak (wiki píše: Např. 3F7H reprezentuje hodnotu, které v desítkové soustavě odpovídá číslu 3×162 + 15×161 + 7×160 = 1015.)

Editováno 7.3.2020 8:33
 
Nahoru Odpovědět
7.3.2020 8:32
Avatar
Caster
Člen
Avatar
Caster:7.3.2020 10:59

Při převodu HEX na DEC je potřeba postupně dělit HEX číslo násobky 10 např.
0x1DD82DB4 t.j. 500706740 (dec) / 100000000 (tj. 10E8) = 5, 5 převést na ASCII a uložit do výsledného pole. Pak od HEX odečíst 5 x 10E8 a získaz další cifru dělením 10000000 (10E7) atd.

 
Nahoru Odpovědět
7.3.2020 10:59
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:7.3.2020 14:54
void numToStr(unsigned u, char *str);

int main() {
        unsigned _int32 Latitude = 0x1DD82DB4; // 500706740 (dec)
        char ASCIIdec[20];

        numToStr(Latitude, ASCIIdec);
        return 0;
}

void numToStr(unsigned u, char *str) {
        char c, *p = str;

        if (!u) {
                *str = '0';
                *(str + 1) = '\0';
                return;
        }

        while (u > 0) {
                *(p++) = u % 10 + '0';
                u /= 10;
        }
        *p = '\0';

        for (int i = 0; i < (p - str) / 2; i++) {
                c = *(str + i);
                *(str + i) = *(str + (p - str) - 1 - i);
                *(str + (p - str) - 1 - i) = c;
        }
}
Nahoru Odpovědět
7.3.2020 14:54
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:9.3.2020 20:39

Díky, nakonec jsem to dal na mikrochipu dohromady, nicméně mi někdo poradil, že stačí použít funkci ultoa(LAT, ASCIIdec, 10); ;-) .

#include <atmel_start.h>

char ASCIIdec[9];
unsigned long LAT = 0x1DD82DB4; /* LAT +8 1DD82DB4 = 500706740 / 1E7 = 50.07067 */

volatile unsigned char flag; /* Suppression of insignificant 0 from left (' ') */
volatile unsigned char digit_v, digit_ch;
volatile unsigned long number, multiple_ten;
volatile signed char i, j;

void ASde(unsigned long HEXval) {
    flag = 0;
    number = HEXval;
    multiple_ten = 0x5F5E100;   // 100,000,000
    for (i = 8; i >= 0; i--) {
        digit_v = number / multiple_ten;
        number = number - (digit_v * multiple_ten);
        multiple_ten = multiple_ten /10;
        if ((digit_v == 0) && (flag == 0)) {
            ASCIIdec[8 - i] = ' ';

        } else {
            flag = 1;
            digit_ch = digit_v + '0';
            ASCIIdec[8 - i] = digit_ch;
        }
    }
}

int main(void) {
    /* Initializes MCU, drivers and middleware */
    atmel_start_init();

    ASde(LAT);
//        ultoa(LAT, ASCIIdec, 10);
    asm("nop");

    /* Replace with your application code */
    while (1) {
    }
}
Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět
9.3.2020 20:39
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.3.2020 8:15

Ja bych pouzil binarni rotace a binarni nasobeni x>>4, x&0f.
jinak, mocny google: https://www.itnetwork.cz/dev-lighter/261

private static int ToDec(this string s)
        {
            Dictionary<char, int> dic = new Dictionary<char, int>()
            {
                {'0', 0},
                {'1', 1},
                {'2', 2},
                {'3', 3},
                {'4', 4},
                {'5', 5},
                {'6', 6},
                {'7', 7},
                {'8', 8},
                {'9', 9},
                {'A', 10},
                {'B', 11},
                {'C', 12},
                {'D', 13},
                {'E', 14},
                {'F', 15},
            };
            int result = 0;
            int n = s.Length -1;
            foreach (var c in s)
                result += (dic[c] * (int)Math.Pow(16,n--));
            return result;
        }

Misto deleni pouzivaji aritmeticke rotace, coz by melo byt tak o dost rychlejsi.

 
Nahoru Odpovědět
10.3.2020 8:15
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.3.2020 8:19

Aha, ni, to vypadalo, ze si chces udelat vlastni funkci :) Jinak teda, jak uz tu psali, kdyz pouzivat 16tkovou soustavu, tak v tech cislech musi byt 16 a ne 10. Cili x4 nebo x/16, x4 nebo x*16.

 
Nahoru Odpovědět
10.3.2020 8:19
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:10.3.2020 19:06

K čemu potřebuješ takovýto typ převodu? Zejména tu část, kde chceš číslo reprezentovat jako jeho ASCII řetězec. Přístup k jednotlivým bitům daného čísla Ti nestačí? Pokud jsou již data v paměti, pak je převádění z jedné soustavy do druhé zbytečné, neboť je to pořád ta samá hodnota, interně reprezentována binárně.

Podívej, jak snadno lze číslo z paměti v jakékoli soustavě vypsat do lidsky čitelné podoby.

#include <stdio.h>

void intToBin(unsigned int num);
void showValue(unsigned int num);

int main(void) {
        unsigned int oct = 03566026664; // 8
        unsigned int dec = 500706740;   // 10
        unsigned int hex = 0x1DD82DB4;  // 16

        intToBin(oct);
        intToBin(dec);
        intToBin(hex);

        showValue(oct);
        showValue(dec);
        showValue(hex);

        return 0;
}

void intToBin(unsigned int num) {
        for (int i = 31; i >= 0; i--) {
                if (num & (1 << i)) putchar('1');
                else putchar('0');
        }
        putchar('\n');
}

void showValue(unsigned int num) {
        unsigned int val = 0;
        for (int i = 0; i < 32; i++) {
                val += num & (1 << i);
        }
        printf("%d\n", val);
}
Nahoru Odpovědět
10.3.2020 19:06
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:10.3.2020 21:37

Data, která pořizuje jednočipový mikroprocesor (6x6x1 mm) a GPSka (4,5x4,5x1 mm) a posílá je přes síť IoT na server, musím někde převést na ASCII znaky, které potřebuje aplikace Android, kterou vytvářím, pro zobrazení trasy pohybu (polohy) na mapě světa. Všechno navrhuji a programuji sám ;-).

 
Nahoru Odpovědět
10.3.2020 21:37
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:10.3.2020 23:09

Takže takový GPS Tracker. :-) To je rozhodně zajímavý projekt, který se dá dále rozšiřovat o spoustu užitečných vychytávek. Tedy GPS Ti získává souřadnice a posílá Ti je v komprimované podobě (hex číslo) na server. Komprimovaná data obsahují všechny potřebné souřadnice nutné pro přesné získání polohy. Tyto data potřebuješ získat aby si je mohl spárovat s mapou, na které poté zobrazíš výslednou cestu.

Pak získání přístupu k jednotlivým číslicím může mít své opodstatnění. A nejsou ta data přesně uložena ve spodních a horních dvou bytech? Pošli ukázku poslané informace za jednotku času a to co by to mělo představovat. Třeba se dá něco optimalizovat lépe. :-)

Nahoru Odpovědět
10.3.2020 23:09
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Odpovídá na DarkCoder
Caster:11.3.2020 14:16

Zkusil jsem spustit tvůj kód výše ve Visual Studiu:

0001110111011­0000010110110110100
0001110111011­0000010110110110100
0001110111011­0000010110110110100
500706740
500706740
500706740

Dnes mi kurýr přivezl vývojovou desku s jednočipovým MCU z Dallasu, tak se do toho pustím.

Data jsou uložena jako long uint (32 bitů) ve formátu Little Endian.

 
Nahoru Odpovědět
11.3.2020 14:16
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:11.3.2020 15:24

Ano, to je správný výstup programu. Ukazuje to, že v paměti jsou všechny číselné soustavy rovny, přístup k jednotlivým bitům proměnné a lidský čitelný výstup číselné proměnné v načtené v libovolné číselné soustavě.

To se kurýr docela proletěl. Že se jedná o celočíselnou 32bit proměnnou je jasné, šlo mi o obsazenost bitů pro tu kterou proměnnou v příchozích datech.

Nahoru Odpovědět
11.3.2020 15:24
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:12.3.2020 10:43

Jak jsem již psal, vývojová deska včera dorazila a na LoRaWAN síti jsou již první zkušební data. Čekám, až mi z Číny dorazí logický analyzátor na I2C sběrnici abych doladil načítaní dat z GPSky. Něco jiného je zkoušet funkčnost I2C přes Arduino (funguje) a jednočipový mikrokontrolér.

 
Nahoru Odpovědět
12.3.2020 10:43
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 15 zpráv z 15.