Il 29/03/2013 02:38, Kiuhnm ha scritto:
> On 3/29/2013 1:03, Tommaso Russo, Trieste wrote:
>> La cosa piu' sensata sarebbe di definirlo fra array di N bit.
>>
>> Definirla fra tipi interi e' una scorciatoia tecnica dettata dalla
>> necessita' di economizzare sul numero di tipi diversi, che presenta due
>> inconvenienti:
>
> Non ᅵ questo il motivo. Il motivo ᅵ che i primi linguaggi di
> programmazione si discostavano poco dall'asm sia per motivi di
> efficienza che di appetibilitᅵ.
> Le cose sono rimaste tali tanto a lungo da diventare prassi anche in
> linguaggi di alto livello come Python e Mathematica per i quali non
> sussistono piᅵ motivazioni tecniche.
E' vero, effettivamente anche noi abbiamo un'inutile appendice del colon
e un residuo di coda nell'osso sacro...
Ma le prassi, *anche se funzionano*, non e' detto che siano *corrette* e
quindi che non comportino pericoli. Vedi sotto.
> Questi e altri problemi vengono risolti da linguaggi come Python e
> Mathematica che sono platform-independent.
OK: finche' resti nel loro ambito.
> Per gli altri linguaggi di basso e medio livello esistono gli standard:
> basta consultarli.
Eh... "La cosa bella degli standard e' che ce ne sono tanti tra cui
scegliere." (Andrew Stuart Tanenbaum)
>>> Mathematica, per la cronaca, fa lo stesso e cioᅵ definisce le operazioni
>>> bitwise tra interi. In particolare, gli interi possono avere un numero
>>> illimitato di cifre.
>>
>> ... ecco, appunto. Cosa ti aspetti che restituisca Mathematica, e cosa
>> effettivamente restituisce, come output di
>>
>> 12 XOR NOT 28 ?
Chiedo scusa a tutti: ho scritto 12 XOR NOT 28, ma i calcoli poi li ho
fatti con 28 XOR NOT 12. Poco male, visto che Kiuhnm non ha rifatto il
calcolo, ma ha convertito in binario i miei risultati e individuato il
pattern comune ;-)
la domanda doveva essere quindi:
output di Mathematica per 28 XOR NOT 12?
>> 15?
>> 239?
>> 65519?
>> 4294967279?
>> 18446744073709551599?
> -17, ovviamente.
Eh, eh... la risposta e' brillante, perche' supera l'obiezione di dover
PREdefinire la lunghezza degli array di bit su cui agire: evidentemente
Mathematica implementa gli interi relativi in precisione multipla con
liste di bit (o anche di byte, la granularita' ha poca importanza) e
quando necessario le allunga alla bisogna, propagando agli elementi
aggiunti il bit piu' significativo.
Ma el tacon xe pezo che el buso :-)
Perche' il risultato "-17" non si basa solo sulla convenzione per cui un
array ordinato di bit puo' essere interpretato come la rappresentazione
in cifre binarie di un intero non negativo, che ha solide basi
matematiche (*), ma *anche* sulla convenzione che riguarda la codifica
del segno.
Mathematica usa evidentemente il complemento a 2, e credo proprio che lo
faccia indipendentemente dall'architettura della cpu su cui gira, per
cui finche' si rimane nell'ambito di Mathematica i risultati rimangono
coerenti. Ma la convenzione "complemento a due", per quanto *oggi* molto
diffusa (**), non e' certamente l'unica:
http://en.wikipedia.org/wiki/Signed_number_representations
per cui, se scrivi un codice che contenga, piu' o meno,
int i = 12;
...
if (28 xor ~ i == -17){printf ... }
e lo fai girare su macchine con diversa architettura, su alcune
architetture la printf verra' eseguita, su altre NO.
(*) ma io ho lavorato anche con CPU, IBM serie 360/20, in cui l'unica
rappresentazione possibile in memoria era il BCD: ogni nibble (mezzo
byte da 8 bit) conteneva una cifra *decimale*; l'eventuale segno "-" era
un F nel nibble finale :-)
(**) e ho lavorato con ben due CPU con complemento a 1, CDC serie 6000 e
Univac serie 1101 (leggi "tredici", eh! :-).
>> 2) La trattazione formale dell' Informatica E' Matematica, anche se poi
>> l'implementazione di sistemi adotta alcuni compromessi e scorciatoie
>> sulla base di necessita' tecnico/economiche contingenti (e che talvolta,
>> anzi spesso, si pagano ben piu' care nello sviluppo e manutenzione
>> successivi). Non assegnare a risultati di compromessi tecnici la stessa
>> dignita' delle basi teoriche.
>
> Che ti piaccia o no, l'informatica non ᅵ come il resto della matematica
> e quelli che tu chiami compromessi plasmano anche la teoria.
Ma questo e' proprio il "peccato originale" dell'Informatica, che si e'
cercato di superare, negli anni '70-'90, con la sua formalizzazione: per
farne una tecnologia ingegneristica basata su solide basi scientifiche,
e non piu' un'"arte". ("The art of computing programming" non e' l'arte
di *scrivere* software, ma l'arte di determinare le soluzioni
informatiche a un problema.)
Hai mai scritto *esplicitamente* la dimostrazione di correttezza di una
routine?
Se la tua routine usa features dell'hardware di basso livello, come ad
esempio la rappresentazione del segno nei signed integer, allora fra le
ipotesi *devono entrare anche* queste: ed e' sin troppo facile darle per
scontate e dimenticarle. Il risultato e' spesso una routine che funziona
correttamente su un'architettura, ma esibisce ostinatamente misteriosi
bug quando viene portata su un'altra.
Chi programma in modo difensivo *testa*, all'inizio di ogni routine, che
siano verificate le ipotesi (sia sugli argomenti di input che
sull'architettura) usate nella dimostrazione; e se non lo sono, call
abort(). Ma i test sull'architettura sono decisamente troppo costosi per
metterli all'inizio di ogni routine; e per di piu', prevenirebbero i bug
da porting prevenendo proprio la portabilita'.
La soluzione sta nell'uso di strutture dati astratte perfettamente
calzanti il problema (per questo ho detto: array (o liste) di bit
piuttosto che integer), lasciando agli scrittori di compilatori e/o
librerie hardware dependent il compito di implementarle tenendo conto di
un'architettura (che, *loro* si', devono conoscere molto bene) e di
testare le ipotesi fatte sull'architettura e usate nella dimostrazione
una sola volta, alla prima esecuzione.
> Gli operatori bitwise si studiano nel corso "Architettura dei
> calcolatori" e i miei colleghi ricordano benissimo l'esame dove si
> chiedeva di eseguire operazioni bitwise tra interi da convertire da
> decimale a binario, ecc...
Confermo. (Hanno forse usato il Tanenbaum? E' quello che usiamo qui a
Trieste).
Ma li' si mettono a confronto, appunto, *diverse* architetture,
nell'ottica proprio di saper implementare una struttura astratta usando
le istruzioni e le rappresentazioni dati di basso livello. Compito,
appunto, dei programmatori di sistemi operativi, compilatori e librerie.
(Poi, certo, se un programmatore a livello piu' alto, per memorizzare un
array di 6 o 12 bit, usera' i bit meno significativi di un UNSIGNED
integer di 8 o 16 bit, nessuno gli sparera' per questo... :-) Ma deve
rendersi conto che sta camminando sul ciglio di un burrone.)
> Io invece ci terrei a essere pagato ora :\
Ah, ma lo fai per professione? ;-)
Io ormai sono in pensione e mi ci continuo a divertire. Mi auguro che ti
ci diverta anche tu... :-)