Newsgroup: it.lavoro.informatica
Titolo: Cultura informatica

Il linguaggio COBOL nasce nel 1959, come linguaggio standard per
l’amministrazione degli uffici e il nome sta per
Common business oriented language
, descrivendo precisamente il suo obiettivo.
L’origine così lontana del linguaggio COBOL è responsabile della
prolissità della sua sintassi e dei vincoli di forma nella struttura che
il programma sorgente deve avere. Tuttavia, questo linguaggio è ec-
cezionale nella gestione dei dati, avvicinandosi alle funzionalità di
un sistema di gestione di basi di dati (ovvero un DBMS).
Il linguaggio COBOL è nato da un comitato di utenti e di produttori
di elaboratori, con lo scopo di rimanere uniforme, il più possibile, su
tutte le piattaforme. Generalmente si considera, correttamente, che il
C rappresenti l’esempio di linguaggio di programmazione standard
per definizione, ma i contesti sono differenti: il linguaggio C serve
a consentire la migrazione di un sistema operativo da una macchi-
na all’altra, mentre il linguaggio COBOL è fatto per consentire la
migrazione di programmi applicativi su architetture fisiche e sistemi
operativi differenti.
Il linguaggio COBOL è fatto per poter funzionare su sistemi operati-
vi che possono anche essere privi di qualunque astrazione dell’hard-
ware; pertanto, una porzione apposita nella struttura del sorgente è
riservata alla dichiarazione delle unità fisiche per lo scambio dei dati
(la divisione
‘
ENVIRONMENT DIVISION
’
).
Utilizzando il COBOL
in un ambiente abbastanza evoluto, quanto può esserlo un sistema
Unix, molte informazioni diventano inutili e implicite, ma il fatto che
con questo linguaggio ci sia la possibilità di operare con la maggior
parte degli elaboratori fabbricati dal 1959 in poi, lo rende speciale e
degno di apprezzamento per lungo tempo.
 
 
Il linguaggio COBOL ha subito nel tempo diverse revisioni, indicate
generalmente attraverso l’anno di edizione; un punto di riferimen-
to abbastanza comune è lo standard del 1985.Per quanto riguarda l’ente 
ISO, è disponibile lo standard ISO 1989.
 
e poi
 
COBOL 2002: ISO/IEC 1989:2002.
COBOL 2014: ISO/IEC 1989:2014.
 
 
Francamente con cosa si potrebbe sostituire?
 
-- 
Quando la dittatura è un dato di fatto, la rivoluzione diventa un diritto.
(Victor Hugo)


La domanda e': perche' sostituirlo se fa tutto quel che deve fare e lo 
fa cosi' benino. Che ha pure l'environment division, tanto per rendere 
il programma il piu' possibile dipendente dalla piattaforma di esecuzione.
 


non sai neanche leggere
 
Il linguaggio COBOL è fatto per poter funzionare su sistemi operati-
vi che possono ANCHE essere privi di qualunque astrazione dell’hard-
ware;



Sei tu che non sai capire.
L'environment division l'ho citata solo incidentamente, ma se c'e', tipo 
quella che segue, ce poco da astrarre.
 
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. i486.
OBJECT-COMPUTER. i486.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
   SELECT NAME-ADDRESS-FILE
      ASSIGN TO "D:\PIPPO.TXT"
      ORGANIZATION IS LINE SEQUENTIAL.
   SELECT PRINT-FILE
      ASSIGN TO "D:\PLUTO.TXT".
 
Un programma cosi' potra' funzionare in un sistema non windows?

 Un programma cosi' potra' funzionare in un sistema non windows?
 
Guarda che questo  è un esempio del piffero :-) 
Il Cobol ha tanti difetti, ma si può scrivere: ASSIGN To nomevariabile, dove dentro alla variabile ci carichi un parametro. Questo in almeno 3 versioni di Cobol per Windows o Unix, oltre naturalmente ai mainframe.

 Francamente con cosa si potrebbe sostituire?
 
Con cosa si *PUO`* sostituire? Con qualunque linguaggio multipiattaforma moderno. Java, se e` per questo, GIA` implementa processi di business che, un tempo, sarebbero magari stati progettati in COBOL.
 
Con cosa si *VUOL* sostituire? E` una domanda diversa. La voglia di sostituire COBOL e` legata ai costi di investimento e ai rischi di una migrazione. Non ha NIENTE a che vedere con la qualita` del COBOL come linguaggio.  
 
Guarda che il COBOL non sopravvive perche` e` il miglior linguaggio in circolazione; sopravvive perche` esiste una montagna di sistemi legacy che nessuno (giustamente) si prende il rischio di cambiare, anche considerati i costi. 

 ware;
 
Esattamente come C, Python o Java?
 

 Guarda che il COBOL non sopravvive perche` e` il miglior linguaggio in circolazione; sopravvive perche` esiste una montagna di sistemi legacy che nessuno (giustamente) si prende il rischio di cambiare, anche considerati i costi.
 
Qui si si potrebbe chiedere da dove derivano quei costi. Chiaramente dal fatto che ri-implementare un processo Cobol in un linguaggio diverso e più moderno (Java, C#, C++, Python...) non è banale e diretto, nè tecnicamente nè soprattutto progettualmente. Voglio dire, se estraessi con tempo e fatica la logica da N-mila righe di Cobol, ma poi potessi implementarla in uno di talki linguaggi con 1/100 del codice (e quindi un 1/100 dei tempi di codifica, test, ecc.) allora il rischio ed il costo sarebbero assolutamente accettabili. Invece non è così, ecco pertanto che resteranno in giro milioni di righe di Cobol, Rpg, C, VB, Fortran, Pascal, ecc. Nei secoli dei secoli. Amen. :-)

Voglio dire, se estraessi con tempo e fatica la logica da N-mila righe di Cobol, ma poi potessi implementarla in uno di talki linguaggi con 1/100 del codice (e quindi un 1/100 dei tempi di codifica, test, ecc.) allora il rischio ed il costo sarebbero assolutamente accettabili. 
 
I termini giusti sono: "se estrarre la logica da N-mila righe di codice richiedesse poco tempo e poca fatica", allora il costo sarebbe probabilmente accettabile, mentre il rischio di rifare tutto rimarrebbe altissimo. 
Ma in un mondo che non sia quello di Willy Wonka, estrarre "con tempo e fatica" significa sborsare soldi per pagare quel tempo e quella fatica. Nella maggior parte dei casi, non val affatto la pena farlo.


Una cosa che purtroppo sembra che nessuno abbia pensato è una aggiunta 
al C++ nella std lib di una classe big_num (numero fixed point con cifre 
a piacere).
Non che non si possa fare (il sottoscritto ne ha una) ma se avessero 
aggiunto allo std una lib di questo tipo avrebbero potuto 
ufficializzarlo come sostituto di COBOL anche per il business dove 
occorrono calcoli matematici con fixed point.
 
 

 Il Cobol ha tanti difetti, ma si può scrivere: ASSIGN To nomevariabile, dove dentro alla variabile ci carichi un parametro.
Guarda che si trattava della environment division, non tanto l'assign in se.

 occorrono calcoli matematici con fixed point.
Personalmente non ho mai visto un dato numerico, in applicazioni 
contabili/gestionali, che non potesse essere espresso con un Double o 
con un Long (java) senza perdita d'informazione. Poi che i fixed point 
siano davvero obbligatori, ne possiamo discutere.
 


Un floating point non puo garantire sempre una determinata precisione.
E' per questo che i fixed point sono utili.
Sui long o long long possono andare bene con calcoli interi, ma usarli 
come fixed point con decimali > 0 sono alquanto scomodi.
In C++ poi non viene rilevato errore per overflow/underflow.
 
 
 

 Ma in un mondo che non sia quello di Willy Wonka, estrarre "con tempo e fatica" significa sborsare soldi per pagare quel tempo e quella fatica. Nella maggior parte dei casi, non val affatto la pena farlo.
 
Bè, certamente solo a Willi Wonka ed a te può venir in mente di estrarre la logica e tenertela lì sul comodino, senza farci un cacchio :-)
Avere i processi di business estratti da una catasta di programmacci qualsivoglia, e messi in bella copia, sarebbe oro puro per una azienda. Siccome però si sa bene che, dopo, reimplementare il sistema usando quella logica ti farà sputare sangue, tempo e dobloni pure usando i più moderni ritrovati dell'IT, in molti casi non si fa. Perchè il costo totale è la somma dell'estrazione della logica PIU' la reimplementazione.
 
 
 
 
 

 Guarda che si trattava della environment division, non tanto l'assign in se.
 
Hmm, quindi il problema non  è l'assign con il path Windows scolpito dentro (ovviamente se mi fai un programmaccio C, Java, ecc. con dentro scolpito il path di Unix il problema sarebbe uguale). Quindi quale sarebbe il problema specifico del Cobol? Sono curioso.
 


Ma non e' propriamente un problema, diciamo che e' una caratteristica 
del linguaggio. La mia citazione/obiezione era rivolta solo al fatto che 
l'environment division specifica, o almeno puo' farlo, il sistema di 
compilazione e quello di esecuzione la qual cosa limita la portabilita'. 
Ovvio che i sorgenti si possono cambiare, io pero' non cambierei una 
environment division a cuor leggero in un programma fatto 40 anni fa da 
uno che chissa' dov'e'.

 come fixed point con decimali > 0 sono alquanto scomodi.
Dipende dal linguaggio. In C utilizzare i decimal non e' affatto comodo, 
lo stesso dicasi per i BigDecimal o BigInteger in java dove gli 
operatori aritmetici te li scordi. Per non parlare degli arrotondamenti, 
che con numeri fixed-point spesso diventano dei troncamenti.
Certo che se fai programmi RPG o COBOL, chi te lo fa' fare di usare i 
floating-point?
 

 uno che chissa' dov'e'.
 
Ti devo tirare le orecchie, visto che tutto ciò che è scritto dopo il punto finale di quelle istruzioni è trattato dai compilatori (sicuramente tutti quelli attuali) esattamente come commento, cioè ignorato. 
 
 


Non e' un  problema tanto di grandezza ma di cifre decimali
 
Es:
  un fixed point la puoi simulare con un long,implicitamente hai 2 dec 
(ad esempio)
Devi fare una somma con un altro long che implicitamente ha  3 cifre
Ti devi ricordare che il primo lo devi prima moltiplicare per 10 e poi 
fare la somma ed il risultato e' un long che implicitamente contiene 3 dec.
Senza contare gli eventuali overflow dove non hai errore (in C/C++)
Ecco perche' i fixed point sono comodi nei calcoli finanziari ed altro.
Ed ecco il motivo per qui ho una serie di classi C++ per queste cose.
In C  esiste anche la lib di gnu per gestire i big number ma non e' 
affatto comoda da usare, il suo uso e' abbastanza complesso.
 
In C++ con una classe si puo scrivere tranquillamente
 
A=B + C
 
dove A,B e C sono dei fixed point ed in piu lanciare una eccezione in 
caso di overflow/underflow (nel caso che  A non potesse contenere il 
risultato)
 
 
 
 
 
 

 quelli attuali) esattamente come commento, cioè ignorato.
Confesso che saranno almeno 20 anni che non metto mano in un programma 
COBOL (il reference che ho in mano risale al 1994), non tanto per indole 
ma per mancanza di progetti COBOL. Mi e' capitato in passato di migrare 
programmi COBOL su as400 e il compilatore non era contento. Puo' darsi 
che la versione attuale si comporti come dici tu, in ogni caso il 
debugging-mode si attiva nella sezione source-computer, mentre altre 
opzioni di programma (es. ottimizzazione, sort-sequence, etc.) stanno 
nella sezione object-computer, quindi sospetto che l'environment non 
possa essere completamente ignorato. Direi anche che e' possibile che 
siano estensione del cobol per as400 ma, limite mio, e' quello che ho 
utilizzato le ultime volte che ci ho messo mano.
 

 Ecco perche' i fixed point sono comodi nei calcoli finanziari ed altro.
Oltre ai problemi di troncamento, che spesso sono la causa di 
squadratura dei conti, anche i fixed-point hanno gli stessi problemi di 
overflow, soprattutto nei calcoli intermedi dove la diagnosi 
dell'overflow diventa anche piu' complicata.
 


Hai ragione, in SOURCE-COMPUTER c'è l'opzione "DEBUGGING MODE" che potrebbe avere qualche utilità,  ed altre opzioni in OBJECT-COMPUTER.
Comunque la dipendenza non  è tanto dal s.o., quanto dal compilatore, come accade anche per altri linguaggi.


Basta gestirli (gli overflow/underflow)
E quello che ho fatto quando mi sono costruito le classi per gestire i 
fixed point.
 
 


Magari gli overflow, ma i troncamenti generati dai fixed-point?


Nelle operazioni aritmetiche non avvengono troncamenti.
L'unico troncamento possibile e' quando si porta nel risultato
 
Es:
 
fixed_number<5,2> A; // fixed number con 3 interi e 2 decimali
 
fixed_number<7,3> B; // fixed number con 4 interi e 3 decimali
 
 
cout << (A + B); # esegue il calcolo con la precisione maggiore tra i 
due quindi 7,3
 
 
fixed_number<6,2> C=A + B;
 
Se la somma supera 9999.99 si ha un eccezione per overflow ma se il 
risultato fosse 55.999 in A andrebbe a finire 55.99
E' comunque sormontabile (sia l'overflow che il troncamento) usando una 
classe che gestisca il numero di interi/decimali in modo dinamico
In questo ultimo modo il limite di cifre (nel mio caso) e' il valore 
massimo di un unsigned long (almeno 4G cifre) che occupano 2G di spazio 
di memoria + mezzo byte per il segno (i numeri sono immagazzinati 
internamente in formato BCD simile ai comp-3 segnati del COBOL).
 
 
 
 
 

 Nelle operazioni aritmetiche non avvengono troncamenti.
[...]
Evidentemente non mi sono spiegato.
Ad esempio, abbiamo una fattura con un certo numero di righe, ogni riga 
contiene l'imponibile e l'imposta, dove l'imposta viene calcolata riga 
per riga, ovvero imponibile * 0.21.
Alla fine delle righe devo calcolare i totali, ho due possibilita' per 
ottenere l'imposta totale: moltiplico la somma degli gli imponibili di 
riga per l'aliquota, oppure sommo le imposte di riga.
Vorrei che i totali ottenuti in entrambe le forme fossero esattamente 
uguali a meno di due decimali.
E' evidente che se il campo imposta di riga (fixed-point) non ha uno 
scale (numero di decimali) sufficiente, potro' ottenere il risultato 
voluto solo casualmente, ovvero anche applicando un arrotondamento riga 
per riga, potro' ottenere il risultato esatto solo se gli arrotondamenti 
si compensano. Non ci ho ragionato molto, ma a occhio direi che la 
distribuzione statistica dell'errore che sqaudra il conto, sia 
dipendente dal numero di righe presenti nella fattura dallo scale 
utilizzato ma anche dagli importi.
 


E se fai i calcoli semplicemente usando l'aritmetica a precisione 
dinamica non avvengono arrotondamenti come ho spiegato.
 
 
 
 
 


IMVHO  non hai capito l'esempio della fattura.
 
Per prassi gli importi (imponibile ed iva )
 vengono stampati con due decimali.
 
In generale, l'arrotondamento della somma e' diverso
dalla somma degli importi arrotondati.
 
Per cui, se una fattura "quadra"
(ossia, l'imposta calcolata sul totale imponibile
e' uguale alla somma delle imposte calcolate su ciascuna riga )
e' un caso particolare.
 
ciao
fm 
 
 
 
--- news://
freenews.netfront.net/
 - complaints: 
ne...@netfront.net
 ---

 dinamica non avvengono arrotondamenti come ho spiegato.
Questa e' la tua soluzione, ovvero un processo che tenga conto della 
magnitudo dell'errore. La mia si basa su numeri (double) per cui 
l'errore e' confinato oltre la 16ma cifra significativa, se tale errore 
e' accettabile non ho bisogno di altro.
Nell'esempio sopra, se l'importo e' intero ovviamente lo scale richiesto 
e' 2. Ma se l'importo non e' intero, ma anzi un valore calcolato tramite 
fattori decimali con diverse dimensioni, ad esempio (caso piu' che 
frequente in ambito contabile/gestionale)
prezzo unitario (7.2) quantita' (7.3) sconto1 (3.2) sconto 2 (3.2) 
sconto3 (3.2) va da se che ad ogni risultato intermedio lo scale 
richiesto aumenta, e l'errore atteso di un double e' ancora piu' che 
accettabile.


A tal proposito, ti cito un corso del prof M.Malcangi del politecnico di 
Milano, pubblicato da Maggioli editore nel 2008 col titolo "Embedded 
system hardware technologies". Non ho un link, ma con 8 euro te la 
dovresti cavare.
Nell'introduzione, al paragrafo dove parla della precisione dei numeri, 
dice che, in assenza di vincoli hw, il formato floating-point, pur non 
estendendo la precisione, estende la dinamica numerica mantenendo la 
precisione, quindi in prima istanza e' da preferire a quello fixed-point.


Lascia stare la fattura.
I calcoli si possono fare a precisione quanto basta e lo decide 
automaticamente il computer in base ai valori dell'espressione.
 


Il tuo professore allora sbaglia oppure crede un fixed point possa 
essere deciso a solo precisione fissa.
Non è cosi.
Inoltre un floating point e abbastanza limitato.
Un long double per lo standard IEEE 754 usa 128 bit per un totale di 34 
cifre decimali.
Un fixed point puo avere 4G cifre o anche piu.
Sulla mia macchina a 64 bit un numero massimo di cifre  e' pari al 
valore massimo di un unsigned long,cioe' 4G * 4G cifre.
In pratica il limite sono i tempi di calcolo e la memoria a disposizione.
 
 

 valore massimo di un unsigned long,cioe' 4G * 4G cifre.
Forse intendi che il valore massimo e' 2**64 -1 ovvero 
18.446.744.073.709.551.615 che sono 20 cifre incomplete.
 
 
 


In C++,credo che tu lo sappia,esiste il concetto di classe.
E' possibile costruire una classe fixed point che gestisca il numero 
delle cifre in modo dinamico.
Lascia stare il COBOL per il confronto,i suoi fixed point sono a valori 
fissi decisi a compile time.
 
Ecco un esempio:
 
class dynamic_fixed_point {
	public:
		....
	private:
		unsigned char* v;  // un array che contiene le cifre,è allocato nella 
memoria dinamica
		size_t  ndigits; // numero di cifre (interi + decimali)
		size_t ndecs; // numero di cifre decimali
};
 
 
 
Ed ecco che v puo contenere tante cifre quando è il valore massimo di 
ndigits  quindi a 64 bit, proprio 2**64 -1 cifre almeno teoricamente.
I limiti sono la memoria ed i tempi di esecuzione nelle varie operazioni 
aritmetiche.
Per semplificare non ho fatto l'esempio dove le cifre sono impaccate in 
formato BCD + il segno ma per spiegare il concetto non serve.
Il prezzo da pagare rispetto ad un fixed point a numero cifre decise a 
compile time è la memoria occupata da ndigits e ndec.
La size dell'array v dipende dal formato interno adottato ma è comunque 
una formula (funzione) il cui risultato dipende da ndigits.
 
 
Invece qui una classe per gestire i fixed point le cui cifre sono decise 
a compile time proprio come in COBOL:
 
 
template <size_t NDIGITS,size_t NDECS>
class fixed_point {
	public:
 
	private:
		// ricava la size dell' array da NDIGITS
		// la funzione  e' valutata a compile time
		static constexpr size_t sz()const { ... }
		unsigned char v[sz()];
};
 
In questo caso viene usato lo stack pur essendo piu limitato come size 
rispetto allo heap.
Notare che internamente la memoria occupata e' solo quella dell' array v.
 
 
 
Spero di essere stato chiaro con questi due esempi.
 
 
 
 
 
 
 

 fissi decisi a compile time.
[...]
D'accordo, esattamente come il BigDecimal in Java.
Io ovviamente parlavo di tipi primitivi.


Non esiste un tipo primitivo fixed point in C++ e neanche in Java.
 


Guarda che questo confronto e' nato proprio nei casi in cui esistono, 
dove io sostenevo che in determinati casi l'uso dei floating-point era 
per certi aspetti preferibile.
 
Nel C++ per as400 c'e' il tipo numerico decimal che definisce appunto 
numeri fixed-point, ovviamente non dinamici, che ha la funzionalita' dei 
numeri packed.
 


Ma nel mio post iniziale mi riferivo ad una o piu classi da aggiungere 
alla std lib del C++,non ho mai accennato ad un tipo primitivo che 
comunque lo riterrei superfluo.
il C++ ha tutti gli strumenti per evitare questo.
Se il compilatore C++ sul tuo AS400 ha un tipo primitivo decimal esso 
non è std,ed io mi riferisco sempre al C++ std in modo implicito.
In quanto tra l'uso  floating point vs fixed_point hanno tutti e due 
pregi e difetti.
Usare l' uno o l'altro dipende dall' applicativo e dalla sensibilità del 
programmatore.