Newsgroup: it.comp.lang.visual-basic
Titolo: Disgressione: Variant e Decimal

Ho trovato questa definizione (che non è completa, quelle completa è qui e
non capisco la doppia definizione
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm
/chap6_7zdz.asp):
struct tagVARIANT
    {
    union
        {
        struct __tagVARIANT
            {
            VARTYPE vt;
            WORD wReserved1;
            WORD wReserved2;
            WORD wReserved3;
            union
                {
                LONGLONG llVal;
                [...snip...]                }    __VARIANT_NAME_3;
            }    __VARIANT_NAME_2;
        DECIMAL decVal;
        }    __VARIANT_NAME_1;       [...snip...]
}
Sembrerebbe quindi che il tipo decimal sia completamente contenuto nei 16
bytes del variant, anzi, sembra un suo alias.
Però allora non capisco come sia possibile che il tipo Decimal sia di 12
byte... ancora 4 byte usati per qualche informazione aggiuntiva, tipo il
numero di decimali?
Ciao
--
NeoDataType : 
http://www.neodatatype.net
Sito Comune : 
http://www.it-lang-vb.net

 
ciao
CCCP++Mario


 DECIMAL DecVal;
Un DECIMAL e' un tipo dati strutturato nel seguente modo
typedef struct  tagDEC
{
 USHORT wReserved;
 BYTE scale;
 BYTE sign;
 ULONG Hi32;
 ULONGLONG Lo64;
} DECIMAL;
composto da 16 byte di cui i primi due non sono utilizzati.
Ciao
oregon

 Un DECIMAL e' un tipo dati strutturato nel seguente modo
bene ! Ecco finalmente chiarito l'arcano.
Pensavo (sono rimasto al 486 però, lo ammetto) che ci fosse la 
possibilità di "vedere" direttamente la memoria a pezzi di 12 
byte dal pentium in su, ma era una sensazione fallace.
Ricordo che il vecchissimo Tasm supportava un tipo di intero 
chiamato TByte (o qualcosa di simile, cmq era un casting di un 
puntatore far ad una sequenza di 10 (!) byte, cose tipo JMP 
[TBYTE PTR address]  etc), ma da come hanno implementato il 
decimal pare non si vada l'oltre gli 8 byte (dell'ULONGULONG). 
Come mai ? Il pentium non riesce a vedere la ram direttamente 
con una "granularità" maggiore di 8 byte proprio a livello di 
istruzioni asm ? Che tu sappia, era inevitabile la segmentazione 
in due variabili distinte per la parte low e high ?
cmq, in fine, si è potuto dirimere la questione che in effetti 
il decimal è interamente contenuto nella variant (e già le cose 
vanno meglio di quanto si fosse temuto, eh eh he).
ciao
CCCP++Mario


Soviet_Mario wrote some cazzatas:
 >Ricordo che il vecchissimo Tasm supportava un tipo di intero 
 >chiamato TByte (o qualcosa di simile, cmq era un casting di un 
 >puntatore far ad una sequenza di 10 (!) byte, cose tipo JMP 
 >[TBYTE PTR address]  etc),
ovviamente questa chicca è frutto solo della digitazione a 
neuroni scollegati, in quanto non ha nessun senso definire un 
target ad 80 bit per un salto, near o far che sia, in quanto gli 
indirizzi erano al massimo a 32 bit.
In realtà il TByte era la comoda interfaccia memoria/stack 
interno del coprocessore e viceversa (dato che all'epoca del 
chip matematico, tipo waiteck 387 e 487, questo internamente 
lavorava appunto ad 80 bit).
Di conseguenza il TByte di allora non era per niente usato come 
un intero come avevo detto, ma era la controparte assempler (e 
macchina) del tipo LONG DOUBLE del CPP, ossia un floating point 
a precisione estesa.
Quindi avrei potuto scrivere esempi tipo
fld [TBYTE PTR CX]
fstp [TBYTE PTR address32]
al massimo, non certo JMP o simili
ciao
CCCP++Mario


AUTO LOL ! ! !
dopo il post di Lokar sullo stile di scrittura anni 80 e la 
formattazione alla cazzo di cane, m'è presa la curiosità e ho 
controllato l'ordine grafico di una mia risposta .... my god 
(l'ho fatta a mano, lo ammetto, in genere lascio fare a mozilla. 
Non aggiungerò mai più i segni di maggiore a mano, giuro !)
ecco qui la perla


 [SNIP]
Sono, contento di averti fatto sorridere con il post nell'altro thread =)
Per contro sono altrettanto lieto di leggerti/vi in questo thread
interessantissimo dal punto di vista tecnico =)
Grazie!
Lokar.magari.tutti.i.thread.fossero.di.questa.levatura
-- 
Sito Comune: 
http://www.it-lang-vb.net/
Manifesto: 
http://www.it-lang-vb.net/docs/Manifesto.txt
Statuto: 
http://www.it-lang-vb.net/docs/Statuto.txt
UGIdotNET - 
http://www.ugidotnet.org

  >segmentazione in due variabili distinte per la parte low e high ?
Ciao Mario,
il TBYTE e' effettivamente un tipo di dati (Ten Bytes) che permette
la rappresentazione dei long double ad 80 bit trattati internamente
dal coprocessore matematico tuttora. Anche se le librerie di VC
trattano i long double con 64 bit (e operano tutte le conversioni
del caso), i calcoli sono effettuati a 80 bit dalla FPU.
Anche in VC6 puoi rappresentare questo tipo di dati con le semplici
righe seguenti
  BYTE tb[10];
  _asm fld TBYTE PTR tb;
che una volta compilate diventano
00401028 DB 6D F4             fld         tbyte ptr [ebp-0Ch]
ma, ovviamente, il tipo dati lo puoi usare solo "nell'ambito" degli
opcode della FPU.
Per quanto riguarda il tipo ULONGLONG, esso e' compilato cosi'
13:       ULONGLONG a;
14:       a=1;
0040102B C7 45 EC 01 00 00 00 mov         dword ptr [ebp-14h],1
00401032 C7 45 F0 00 00 00 00 mov         dword ptr [ebp-10h],0
e quindi con 2 istruzioni per la parte alta e la parte bassa.
Questo vuol dire che per 12 byte la scelta "giusta" e' appunto
32 bit + 64 bit ovvero un ULONG e un ULONGLONG (il segno e'
a parte nella struttura).
E' possibile usare anche i registri MMX per le istruzioni che
usano direttamente valori a 64 bit
18:       BYTE d64[8];
19:       _asm movq mm6,d64
00401039 0F 6F 75 E4          movq        mm6,mmword ptr [ebp-1Ch]
e in teoria anche i registri a 128 bit ma l'istruzione
21:       BYTE d128[16];
22:       _asm movaps d128,xmm1
movaps non e' supportata dal VC (immagino che il MASM lo faccia ...).
Ciao
oregon

 oregon