[ aleksazr @ 03.04.2012. 21:39 ] @
Imam dve varijable tipa WORD (unsigned, 16 bita), a rezultat treba da bude DWORD (unsigned, 32 bita):
nešto ovako: DWORD = WORD1 - WORD2.

Želim da procesor oduzme unsigned WORD - unsigned WORD i dobije unsigned WORD.
Zatim da ga zero-extendira na unsigned DWORD.
(za one koji znaju X86, to je SUB AX,CX i MOVZX EAX,AX)

Napisao sam rutinu DWORD sub (WORD word1, WORD word2)

prvo sam napisao ovako:
return (DWORD) (word1 - word2);
jer sam očekivao da će kompajler oduzeti u16 - u16 i dobiti u16, pa ga ja castujem u u32.

ali to nije radilo, pa sam promenuo u sledeće:
return (WORD) (word1 - word2);
ovo radi, ali nemam pojma da li treba tako, ili možda treba ovako
return (DWORD) ((WORD) word1 - (WORD)word2);

ili ko zna koja varijacija...?


Da završim sa...
Jezik C sam počeo da koristim tako što sam prosto seo i pisao program :) Baš tako.
Pa mi fale neke osnove iz C jezika. Pre toga sam godinama radio u asembleru, pa mi je sam CPU blizak.
99.9% vremena mi ide bez problema, ali onda naletim na ovako nešto.
[ Nedeljko @ 04.04.2012. 12:31 ] @
Ako hoćeš da račun obaviš u 16 bita, a da onda pretvoriš u 32, onda ti sve varijante koje si napisao obavljaju posao. Ako nećeš funkciju, nego makro, onda

Code:
#define sub(w1, w2) ((DWORD)((WORD)(w1) - (WORD)(w2)))


No, naravno da je bolje imati inlajn funkciju

Code:
inline DWORD sub(WORD w1, WORD w2)
{
    return w1 - w2;
}


No, ti si napisao da ti onaj kod ne radi, pa napiši neke konkretne ulaze i izlaze koje očekuješ za te ulaze.
[ aleksazr @ 04.04.2012. 13:01 ] @
Code:
inline DWORD sub(WORD w1, WORD w2)
{
    return w1 - w2;
}


sub(0,1) mi vraća 0xFFFFFFFF, dok ja želim da mi vrati 0x0000FFFF.

Želim da procesor oduzme unsigned WORD - unsigned WORD i dobije unsigned WORD.
0000 - 0001 = FFFF

Zatim da ga zero-extendira na unsigned DWORD
0000FFFF

Kao što rekoh, ovo radi
return (WORD) (word1 - word2);

možda bi bilo pravilnije da piše ovako (i ovo isto radi)
return (DWORD) ((WORD) (word1 - word2));

Koliko se sećam, pročitao sam negde da kompajler ne oduzima WORD - WORD,
nego prvo oba worda konvertuje u dword... tako nešto, nisam siguran.
Kako se zovu takva pravila na engleskom? (da mogu da googlam)
[ djoka_l @ 04.04.2012. 13:16 ] @
Ako hoćeš da budeš siguran uradi:

return (w1-w2) & 0x0000ffff;
[ aleksazr @ 04.04.2012. 13:20 ] @
Citat:
djoka_l: Ako hoćeš da budeš siguran uradi:

return (w1-w2) & 0x0000ffff;


Da, ali ja bih prvo da znam kako se zovu ona pravila (ako postoje, a nešto mislim da postoje).
Da ubuduće nemam iznenađenja na tu temu.
[ djoka_l @ 04.04.2012. 13:31 ] @
Evo primer koji radi ispravno, bez maskiranja bitova:

Code (c):

#include <stdio.h>
unsigned int sub( unsigned short w1, unsigned short w2) {
return (unsigned short)(w1-w2);
}
int main() {
  unsigned int a;
  a=sub(0,1);
  printf("%8x\n", a);
}
 
[ aleksazr @ 04.04.2012. 13:53 ] @
Taj primer sam napisao u prvom postu.
Tu nije jasno zašto se kompajler ne buni kad se return vrednost castuje u WORD, a rutina treba da vrati DWORD.
[ djoka_l @ 04.04.2012. 13:57 ] @
Ono što ti, u stvari, pitaš je da li postoje pravila za implicit casting.
Ne postoji standard!

Ono što je recimo po standardu je da su dužine integer tipova long>=int>=short ali nigde nije navedeno kolike su ove dužine. To zavisi od kompajlera i mašine na kojej se kompajlira. Takođe byte WORD DWORD char zavise od mašine. Uzmeš uputstvo za kompajler i proveriš. pa onda proveriš na primerima.

Imao sam, na primer, problem sa intiger owerflow matematikom kada sam portovao program na Tru64 unix, gde je int bio 64 bita, dko je na originalnoj mašini bio 32 bita.

Rešenje:

#ifdef TRU64
#define INT _int32
#else
#define INT int
#endif

Pa nadalje int varijable definišeš kao INT
[ Nedeljko @ 04.04.2012. 14:21 ] @
Evo koda koji radi ispravno

Code:
#include <iostream>
#include <windows.h>

using namespace std;

inline DWORD sub(WORD w1, WORD w2)
{
    return (WORD)(w1 - w2);
}

main()
{
    cout << sub(0, 1) << endl;
}