Professional Documents
Culture Documents
01-Koncepti Proceduralnih Jezika PDF
01-Koncepti Proceduralnih Jezika PDF
1
Smjerovi razvoja programskih jezika
U početku, ... programi su pisani u strojnom kodu, sekvence bitova, obično u heksadecimalnoj notaciji, predstavljali su i
naredbe i podatke u računalu.
Primjer:
34020005
0000000c
3c011001
Primjer:
mov eax,5
push eax
call absvalue
sub esp, 4
Ovo je lakše razumjeti od binarnih sekvenci, ali i dalje se mora programirati na vrlo niskoj razini - direktno se manipulira s
memorijom i vanjskim uređajima.
2
U asembleru:
o Postoji samo jedan tip podataka - niz bajta.
o Kontrolne strukture su: uvjetni i bezuvjetni skokovi.
o Imena (varijabli i labela) su globalni objekti
o Potprogrami se realiziraju kao prosti skokovi na mjesto izvršenja programa.
o Nije poznat mehanizam prijenosa argumenata funkcije.
Primjer:
sum = 0
do 10 i=1,100
10 sum = sum + a(i)
3
Cobol (Common Business Oriented Language)
Jezik za poslovne aplikacije s bazama podataka. Razvijen početkom 60-tih godina.
Primjer:
multiply i by 3 giving j.
move j to k.
write line1 after advancing
1 lines.
Cobol je:
o Prvi standardizirani programski jezik.
o Još i danas se koristi u komercijalnim aplikacijama.
o Jezik s dosta riječi, pogodan za proste programere.
o Prvi puta otvara diskusiju o potrebi pisanja razumljivog kôda
4
BASIC
BASIC (Beginner’s All-purpose Symbolic Instruction Code) je kreiran na DARTMOUTH College od John Kemeny i
Thomas Kurtz-a 1964. godine kao jezik za ne-profesionalce. To je bio prvi pravi interpreter.
Varijable su zapisivane jednim slovom ili slovom iza kojeg slijede znamenke.
Ne koristi se eksplicitne deklaracije varijabli.
Varijable mogu biti numeričke vrijednosti ili stringovi.
Svakoj naredbi prethodi numerička oznaka, koja se koristi kao oznaka za skokove u programu.
Primjer:
10 REM A SAMPLE BASIC PROGRAM FOR SORTING ARRAY A
20 DIM A(100)
30 FOR I = 1 TO 100
40 INPUT A(I)
50 NEXT I
60 FOR I = 1 TO 100
70 J = I
80 FOR K = J+1 TO 100
90 IF A(K) < A(J) THEN 130
100 T = A(I)
110 A(I) = A(J)
120 A(J) = T
130 NEXT K
140 NEXT I
150 STOP
160 END
Današnje verzije BASIC jezika, primjerice Visual Basic, nemaju značajnije sličnosti s ovim jezikom.
5
Algol 60 (Algorithmic Language)
Razvijen 1960. kao prvi jezik koji je potpuno pogodan za strukturalno programiranje. Direktni je prethodnik jezika Pascal,
C, C++ i Java.
Primjer:
6
Lisp (List Processing Language)
Lisp je razvijen početkom 60-tih godina. U njemu se odstupa od proceduralne (imperativne) osnove programskih jezika, a
uvode se elementi funkcionalnog programiranja
>(+ 1 2 5)
8
>((lambda (x) (* x x)) 10)
100
Karakterisike Lispa:
o Program i podaci se predstavljaju kao liste u prefiksnoj notaciji
o (+ 9 8 7) znači: izraz kojem se rezultat dobije zbrajanjem brojeva 8,8 i 7
o Ne postoji deklaracija tipova varijabli
o Tipovi su svojstva vrijednosti podataka, a ne svojstva varijable ili parametara funkcije.
o Program u toku izvršenja može stvarati i izvršavati funkcije i izraze
o Vrši se automatsko alociranje memorije - koristi se "garbage collection" mehanizam
Pri razvoju jezika prvi put je razvijena i definirana formalna semantika - njome se precizno određuje značenja
programa.
Slijednik Lispa je jezik Scheme koji uvodi i elemente iz Algola (lokalni doseg). Pored Scheme jezika od funkcionalnih
jezika dosta su u upotrebi Haskell, ML, OCaml i F#.
7
Simula 67 (Simulation Algol)
Simula 67 je prvi objektni jezik - uvodi se definiciju klasa
Primjer:
ADA
ADA - jezik je sredinom 70-tih razvijen za U.S. Dept. of Defense
8
C i C++
C je razvijen početkom 70-tih godina, a C++ sredinom 80-tih godina. Oba jezika su prihvaćeni kao temeljni jezici za
"performance-critical applications": izradu operativnih sustava i sistemskog softvera.
Omogućuju platform-independent programiranje. (#define leksičke - supstitiucije)
Oba jezika mogu koristiti i početnici i profesionalni programeri, ali to ne znači da su podesni za početno poimanje
programiranja.
To bolje omogućuju Java i C#. Jednostavnost slijedi iz činjenice da ovi jezici ne koriste pokazivače.
Java
Jezik Java je razvijen krajem 90-tih, kao jezik za izradu distribuiranih mrežnih programa. Glavne karakteristike su :
Jednostavniji je i čišći jezik od C++, što je ostvareno nauštrb brzine izvršenja programa.
Čisti OO jezik - sve konstrukcije jezika se definiraju unutar klase.
Naglasan na sigurnosti, a ne na brzini.
Potpuna neovisnost o operativnom sustavu.
C#
Vrlo je sličan Javi, ali je nešto bliži C++ jeziku nego Java.
Objective C
Objective C je razvijen i korišten na Next i Mac OS sustavima. Preuzima elementa C-a i Smalltalka.
Swift
Apple-ov odgovor na C#
9
Zašto se istražuju novi programski jezici?
1. Znatiželja
Koji drugi oblici jezika mogu biti realizirani?
2. Produktivnost
Standardni proceduralni jezici su vrlo zahtjevni kad treba razvijati softver posebne namjene. U tom slučaju je možda bolje
razviti intepreter za tu posebnu namjenu. Primjerice, jezik Matlab omogućuje jednostavno rješavanje matematičkih
problema.
3. Sigurnost i pouzdanost
I dalje je pitanje sigurnosti izvršenja programa vrlo važno pitanje, koje je možda može bolje riješiti u samom programskom
jeziku.
4. Brzina izvršenja
Jezici C i C++ omogućuju najbrže izvršenje programa na standardnim računalima, međutim nisu pogodni za sustave
računala koji rade paralelno ili distributivno.
10
Poželjne karakteristike programskih jezika
Gledano teoretski, kada programski jezik tretiramo kao dio stroja računala, tada su skoro svi programski jezici ekvivalentni
i pomoću njih se mogu riješiti svi problemi koje je moguće riješiti računalom (Church –Turing teza). Ipak, jezici imaju i
druge, mnogo značajnije funkcije a to je da omoguće apstrakciju, efikasne programe i ugodno programiranje.
Opći su zahtjevi:
o Brzina izvršenja i mali zahtjevi za memorijom.
o Prevođenje brzo i modularno, s pripadnim bibliotekama.
o Komponente jezika trebaju biti "reusable"
11
Programske i jezičke paradigme
Programske jezike dijelimo prema 4 fundamentalna stila - paradigme: proceduralni, objektno orijentirani, funkcionalni i
logički.
Proceduralni jezici
C, Fortran, Pascal, Ada, itd.
a = a + 1;
if (a > 10)
b = 10;
else
b = 15;
a = a * b;
Zašto ovaj program pet procesora ne može izvršiti pet puta brže?
12
Kod proceduralnih jezika funkcije često iskazuju bočne efekte (side effects)
int global=1;
int Mul(int x) {
global = global *x; // side effect – bočni efekt na globalnu var.
return global;
}
int main()
{ // Loše je što
cout << Mul(3) // svaki poziv
cout << Mul(3) // daje drukčiji
} // rezultat
Izlaz:
3
9
Bočni efekti nisu poželjni u programiranju, jer višestruki poziv neke funkcije s istim argumentima daje različite rezultate.
13
Objektno-orijentirani jezici
C++, Java, C#, Smalltalk, Pizza i Python su objektno-orijentirani jezici.
Objekti su aktivni entiteti sa stabilnim stanjem, i sučeljem prema drugim objektima, s kojima se komunicira pomoću poruka
ili metoda.
U definiranju objekata koristi se princip nasljeđivanja, princip komponiranja objekata i princip zajedničkog sučelja
(interfejsa).
Interface (sučelje) u JAVI ili virtualne funkcije u C++ jeziku određuju način komuniciranja s različitim objektima, što
omogućuje da se programi izvršavaju polimorfno (višeoblično).
U C# i Javi sve mora biti deklarirano unutar klase, čak i Main() funkcija, od koje starta izvršenje programa
14
//C++ program
int main()
{
cout << " hello, world "
}
//Java program
class Hello
{
public static void main(String[] args) {
System.out.println("hello, world");
}
}
// C# program
class Hello
{
static void Main() {
System.Console.WriteLine("hello, world");
}
}
15
Funkcionalni jezici
U funkcionalnim jezicima,
Dizajn jezika minimizira bočne efekte uključujući i izbjegavanje upotrebe naredbe pridjele vrijednosti.
16
Logički programski jezici
Prolog je logički programski jezik. U njemu korisnik zapisuje:
o činjenice i
o što program treba obaviti,
o a ne zapisuje se postupak kojim se izvršava program
Primjer:
inOrder( [] ).
inOrder( [ _ ] ).
inOrder([a,b|c]) :- (a < b),
inOrder([b|c]).
17
Koncepti iz programskih jezika
Svaki identifikator ima doseg (scope ) u programu— to je dio programa u kojem je vidljiv identifikator
Životnost (lifetime) — je vremenski interval u kojem identifikator referira memorijski objekt. Obično je životnost
povezana s dosegom identifikatora, tj. objekt traje za vrijeme izvršenja programa iz dosega identifikatora.
18
Dinamički alocirane varijable
U C++ se koristi pokazivače i operatore new i delete. Primjerice, dinamički niz od 6 cijelih brojeva formira se naredbom:
Kada nam više ne treba ova varijabla brišemo je iz memorije operatorom delete:
U Javi i C# se svi objekti i nizovi formiraju dinamički - primjenom new operatora. Dealociranje memorije ne vrši korisnik
već se vrši automatski pomoću mehanizma "skupljača smeća" (garbage collection). Zbog toga, jer u Javi i C# nema
statičkih nizova i objekata, njihova imena, iako predstavljaju pokazivače, tretiraju se kao reference. To pojednostavljuje
zapis programa na način da se članovima struktura i klasa uvijek pristupa pomoću točka operatora.
19
U Javi i C# svi objekti se stvaraju dinamički
class A
{
public void F() { System.out.println("A.F"); }
}
class Test
{
public static void main(String[] args) {
A b = new A(); // dinamički alocirani objekt b
b.F(); // članovima se pristupa pomoću točka operatora
} // iako b stvarno predstavlja pokazivač
}
20
Blok struktuirani jezici
Algol 60, Pascal, C, C++, Java.
Povezivanje identifikatora i deklaracije je obično statično (ili leksičko), ali su moguća i dinamička povezivanja (npr.
pretvorba tipa).
Statičko (ili leksičko ) povezivanje se vrši prije izvršenja programa— za vrijeme kompiliranja
Primjer (C jezik):
int x,z;
void A() {
float x,y;
print(x,y,z); // global var z
}
void B(int y) {
print (x,y,z) // global var x,z
}
21
Blok struktura
U većini slučajeva blok struktura znači:
Postoje varijacije od ovih pravila. U Javi se može koristiti objekt tek kada je kreiran pomoću new operatora,
Primjerice,
...
Object Obj;
...
22
Dinamički doseg
Pod dinamičkim dosegom podrazumijeva se da se za identifikator uzima deklaracija koja je najbliže prema vremenu
izvršenja programa. Taj se princip koristio u ranim verzijama jezika Lisp.
Problem nastaje ako varijabla nije lokalno deklarirana. Primjerice, problem je ilustriran s kvazi-C jezikom
int x;
void print()
{
write(x);
}
main () {
bool x;
print();
}
Kod statičkog povezivanja x se ispisuje u funkciji print() kao tip int, jer je int x, globalno deklariran.
Kod dinamičkog povezivanja, pošto print nema lokalnu deklaraciju za x, ispituje se pozvana funkcija u kojoj je x tipa
bool.
Dinamičko povezivanje je vrlo teško provesti, stoga se ono izbjegava. Ono čak izgleda i bizarno, ali se ipak koristi, i to kod
virtualnih funkcija u C++, C# i Java jeziku.
23
Virtualne funkcije
using System;
class C {
public void DoIt() {PrintIt();}
public virtual void PrintIt() {Console.WriteLine("C rules!");}
}
class D : C {
override public void PrintIt() {Console.WriteLine("D rules!");}
public void TestIt() {DoIt();}
}
class Test{
public static void Main() {
D dvar = new D();
dvar.TestIt();
}
}
24
U jeziku Java – "sve metode su virtualne"
Primjer:
class C {
void DoIt() {PrintIt();}
void PrintIt() {System.out.println("C rules!");}
}
class D extends C {
void PrintIt() {System.out.println("D rules!");}
void TestIt() {DoIt();}
}
class Test {
public static void main (String args[]) {
D dvar = new D();
dvar.TestIt();
}
}
25
Doseg i životnost
Obično se zahtijeva da životnost varijable bude barem jednaka vremenu koji odgovara izvršenu dosega varijable.
Životnost nekih objekata nadmašuje njihov doseg. Primjer za to su static ili own varijable.
void f() {
static int i = 0;
print(i++);
}
Svaki poziv f() ispisuje različitu vrijednost od i (0, 1, ...) . Varijabla i zadržava vrijednost između poziva funkcije.
ML C
Let {
id = val type id = val;
in
statements statements
end; }
26
Strukture i blokovi
Podaci se grupiraju u strukture:
{
float re, im;
re = 0.0; im = 1.0;
}
Ako u strukturu dodamo definiciju funkcija i inicijalizacijski kod (konstruktora i destruktora) dobije se definicija klase:
class complex
{
public:
float re, im;
complex (float v1, float v2){ re = v1; im = v2; }
}
27
Klase
Klasa se koristi za stvaranje jednog ili više objekata
Deklarirane varijable se nazivaju članovi ili polja, a deklarirane funkcije se nazivaju metode ili članske funkcije klase,
Dvije posebne funkcije, kojima se ne zadaje tip, i koje imaju ime klase , predstavljaju konstruktor i destruktor klase
Unutar klase članovi se mogu grupirati s atributom public, private ili protected, što označava razinu dozvole pristupa
članovima klase.
class MyClass {
...
}
Ova naredba pridjele vrijednosti ne mora biti uvijek u C++ izvršena s željenim učinkom.
Pogledajmo slučaj u Javi i C++
28
JAVA
Point () {
dimensions = 2;
coordinates = new float[2];
}
Point (int d) {
dimensions = d;
coordinates = new float[d];
}
}
Point plane = new Point();
Point solid = new Point(3);
plane = solid; //OK u Javi
U Javi je dozvoljeno pridjeljivanje objekata iste klase, iako u ovom primjeru, od dvodimenzionalne točke stvaramo
trodimenzionalnu točku.
29
U C++ postoji problem plitkog i dubokog kopiranja, koji se rješava tako da korisnik sam definira operator pridjele
vrijednosti. Ortodoksni kanonički oblik klase u C++ zahtijeva da se definira a) konstruktor, b) destruktor, c) operator = i d)
kopirni konstruktor:
#include <iostream>
class Point {
public: int main()
int dimensions; {
float *coordinates; int i;
Point (int d = 2) { Point *plane = new Point();
dimensions = d; Point *solid = new Point(3);
coordinates = new float[d]; for (i=0; i<solid->dimensions; i++)
} solid->coordinates[i]=i;
30
Subklase nisu ekvivalentnog tipa
Temeljna se klasa naziva superklasa, a izvedene klase se nazivaju subklase. Također se za temeljnu klasu koristi
naziv roditelj (parent class), a izvedene klase se nazivaju djeca (child classes),
U C++, C# i Javi subklase (ili subtipovi) se stvaraju pomoću nasljeđivanja, ali to ne znači da se te klase istog tipa
Primjer u Javi:
31
C++:
class Point2 :public Point {
public:
Point2() : Point(2) {}
};
class Point3 :public Point {
public:
Point3() : Point(3) {}
};
int main()
{
Point2 *plane = new Point2();
Point3 *solid = new Point3();
for (i=0; i<solid->dimensions; i++)
solid->coordinates[i]=i;
return 0;
}
Izlaz je: 0 1 2
32
Ako se deklarira u C++:
izlaz je: 0 1
33
Generičke klase i parametrički polimorfizam
Postavlja se pitanje, kako se može stvarati napredne strukture podataka koje se mogu primijeniti na različite tipove.
Primjerice, može li se napraviti klasu za vezanu listu koja će moći sadržavati različite tipove podataka.
Najjednostavniji način je primijenjen u jeziku Java, na način da sve klase nasljeđuju jedinstvenu temeljnu klasu Object.
U Javi se onda vezana lista definira sljedećom klasom:
class LinkedList
{
Object value;
LinkedList next;
Object head() {return value;}
LinkedList tail(){return next;}
LinkedList(Object O)
{value = O; next = null;}
LinkedList(Object O,LinkedList L)
{value = O; next = L;}
}
Vidimo da ova klasa sadrži objekte tipa Object. Pošto je referenca objekta u Javi zapravo pokazivač objekta tada se ovom
objektu može pridijeliti objekt bilo kojeg tipa, ali:
o Mora se vršiti pretvorba tipa Object u stvarni tip ako želimo dobiti objekt iz liste
o Za pretvorbu tipa mora postojati definirana klasa. Primjerice ako želimo da lista sadrži cijele brojeve za
pretvorbu tipa nam je potrebna klasa Integer a ne primitivni tip int (jer primitivni tip nije klasa).
34
Primjer, manipuliranje s vezanom listom koja sadrži cijele brojeve :
Očito je ovaj pristup u Javi, a slično je bilo i u prvim bibliotekama C++, dosta nepraktičan. Zbog toga je u C++ uveden
mehanizam predložaka (template) a sada se uvodi u C# i u Javu (probna verzija je dana u jeziku Pizza). Mahanizam
predložaka stvara generičke klase i to se naziva parametrički polimorfizam.
class LinkedList<T> {
T value;
LinkedList<T> next;
Isto kao u C++ parametrički tip se zapisuje u zagradama <>, a stvarni tip se definira pri deklaraciji objekta.
35
Preopterećenje (Overloading) funkcija ili ad-hoc polimorfizam
U klasama se često definira više funkcija (ili konstruktora) s istim imenom ali s različitim parametrima. To zovemo
preopterećenjem funkcije. Primjer:
class MyClass {
int f(int i) { ... }
int f(float g) { ... }
int f(int i, int j) { ... }
}
C++ i Java ne dozvoljavaju de se preopterećene funkcije razlikuju po povratnoj vrijednosti, već moraju biti različiti
parametri funkcije (broj parametara ili tip) To znači da
class MyClass {
int f() { ... }
float f() { ... }
}
nije dozvoljeno.
36
Preopterećenje operatora
C++ i C#, dozvoljavaju preopterećenje (promjenu značenja) postojećih operatora. Primjer:
class MyClass {
int i;
public:
int operator+(int j) { return i+j; }
}
MyClass c;
int i = c+10;
int j = c.operator+(10);
int k = 10+c; // Nije dozvoljeno!
Izraz 10+c nije ispravan jer nije definirano djelovanje operatora + za objekte tipa int i MyClass&. To se može
ostvariti u C++ pomoću friend mehanizma, koji omogućuje pristup private članovima:
class MyClass {
int i;
public:
int operator+(int j) {return i+j; }
friend int operator+ (int j, MyClass& v) {return j+v.i; }
}
MyClass c;
int k = 10+c; // OK!
C++ dozvoljava preopterećenje postojećih operatora. Neki jezici, poput Algola 68 dozvoljavaju definiranje novih operatora.
37
Prijenos argumenata (stvarnih parametara) funkcije
Stvarni parametar ili argument funkcije je objekt koji se deklarira kao formalni parametar funkcije. On ima ime, i
vrijednost i adresu (ukoliko nije konstanta). U funkciju se mogu prenositi sve tri značajke argumenta. Koriste se sljedeći
nazivi za prijenos argumenata u funkciju:
Prenosi se
Vrijednost: Formalni parametar se tretira kao lokalna varijabla koja se inicijalizira na vrijednost argumenta. To je
standardni oblik prijenosa vrijednosti konstanti i skalarnih varijabli u C i Javi.
Referenca: Formalni parametre je pokazivač na stvarni parametar. Koristi se u C++ i C za prijenos nizova i varijabli.
Rezultat: Formalni parametar se tretira kao lokalna varijabla. Njena konačna vrijednost se nakon završetka funkcije
kopira u stvarni argument funkcije.
Vrijednost/Rezultat: Kombinacija dva moda. Formalni parametar se tretira kao lokalna varijabla koja se inicijalizira
na vrijednost argumenta. Nakon završetka funkcije rezultat se upisuje u stvarni argument.
Ime: Formalni parametar predstavlja blok koda (zovemo ga thunk) koji se evaluira da bi se dobila vrijednost ili
adresa argumenta. Koristi se jedino u jeziku Algol.
Read-only (Const): Dozvoljen je argument koristiti samo kao konstantu.
• C jezik koristi se prijenos vrijednosti, jedino se nizovima prenosi referenca (adresa nultog elementa)
• C++ dozvoljava prijenos reference varijable
38
int g(int a, out int b)
• Java: Skalarni tipovi (int, float, char, etc.) se prenose po vrijednosti, a objekti po referenci.
• Fortran: prenosi se referenca (čak i za konstante).
• Ada prenosi vrijednost / rezultat, reference i readonly konstante.
Prijenos po imenu je sličan onome što se kod funkcionalnih jezika naziva "lazy evaluation" (odloženo evaluiranje
argumanta). Kod "lazy evaluation", ne vrši se proračun vrijednosti argumenta već se definira posebna funkcija
suspension— koja daje vrijednost kada ona bude potrebna. Suprotno od "lazy evaluation" je "eagger evaluation" gdje se
argumenti evaluiraju čim su definirani.
39
Ekvivalentnost tipova
Provjera tipova se obično radi za vrijeme kompiliranja – to zovemo static typing.
Provjera tipova se može raditi i za vrijeme izvršenja programa - to zovemo dynamic typing.
Program je tipski-siguran (type-safe) ako nije moguće primijeniti operacije na nekompatibilne tipove podataka.
Čvrsto tipizirani (Strongly-typed) programski jezik zabranjuje formiranje (ili izvršenje) tipski-nesigurnih programa.
Slabo tipizirani (Weakly-typed) programski jezik omogućije formiranje (ili izvršenje) tipski-nesigurnih programa.
Java je čvrsto tipizirani jezik, a C i C++ su slabo tipizirani jezici koji dozvoljavaju da se zaobiđu tipska pravila, primjerice:
int i;
int* p;
p = (int *)i * i;
Sada se p može koristiti kao pokazivač na int premda množenje može rezultirati nedozvoljenim pokazivačem.
Kod kontrole tipova prvo se utvrđuje da li su dva objekta, iz nekog izraza, koji imaju tipove T1 i T2, tipski ekvivalentan.
o ekvivalencija po imenu
o strukturalna ekvivalencija.
40
Ekvivalencija po imenu
Dva tipa su ekvivalentna ako označavaju istu vrst deklaracije.
Primjer:
typedef int i;
int j;
Primjer,
type PackerSalaries = int[100];
type AssemblySizes = int[100];
PackerSalaries salary;
AssemblySizes size;
(a) T N T
(b) Za deklaraciju oblika
Type T1 = T2;
T1 N T2
41
Strukturalna ekvivalencija
Dva tipa su strukturalno ekvivalentna ako imaju istu definiciju članova strukture . Strukturalna ekvivalencija se označava s
S, a definira se na sljedeći način:
(a) T S T
(b) Za deklaraciju oblika
Type T = Q;
T S Q
ako T i Q su definirani pomoću istih konstruktora tipa i na isti način.
salary S size
C i C++ u kontroli tipova koriste strukturalnu ekvivalenciju osim za strukture i klase, kod kojih se koristi ekvivalencija po
imenu. Kod nizova ignorira se veličina niza. Java koristi strukturalnu ekvivalenciju za skalarne tipove. Kod nizova
zahtijeva ekvivalenciju po imenu, bez obzira na veličinu niza. Za klase koristi ekvivalenciju po imenu osim što se može
koristiti podklasa na mjestu gdje je definirana klasa.
42
To znači da za definiranu funkciju:
poziv
fun(new Integer(100));
C, C++ i Java dozvoljavaju pretvorbu tipova, od toga neke pretvorbe se vrše automatski
U C i C++ (ali ne u Javi), cijeli broj se može i "suziti" s mogućim gubitkom bitova:
43