Tutoriel Google Dart – Session 02 – Les Nombres

[Télécharger les sessions 01 et 02 au format PDF]

Dart! langage de programmation structuré pour le web purement orienté objet, a nous deux! 🙂
Allez dans cette session on va essayer d’explorer le monde des nombres toujours en nous basant sur le DartBoard. Si vous venez d’arriver je vous conseil vivement de lire la première session

Manipulation des Nombres

Déclaration et Initialisation

Comme d’habitude on commence avec notre main() et les types que nous utiliserons ici seront soit num (numérique), int (entier), double (nombre à virgule flottante),bool (valeur booléenne tel que vrai/faux) et sinon par défaut var.

main() {

num a=1,b=2, bb=-2, num pi = 3.14159265;
int i=1,y=3;
double z=65.423
……

Les instructions d’affectations

Une variable est identifié par son nom qui doit être unique et son type qui permet de dire ce que cette variable représente (un entier, un flottant, une chaine de caractère, un liste etc…). l’opération la plus courante pour une variable est l’affectation qui consiste à donner à une variable, une valeur qui en principe est en adéquation avec le type.

l’exemple le plus simple est l’affectation simple:

int a=1; double b=3,14, c=13,1019;

on peut stocker dans une variable le résultat d’un calcul ou d’une fonction ce qui donne par exemple:

a=5+3;

Théorie

Une opération mathématique est un processus visant à obtenir un résultat en utilisant un ou des symboles spécifiques appelés opérateurs et nécessitant au moins une expression, aussi appelée un argument ou « une opérande« .

Une opération aura donc cette forme:

Résultat [opérateur d’affectation] opérande1 [opérateur1] opérande2 [opérateur2] .. opéranden

par exemple:

x = a + b – 2 * 3 + c / 2

L’opérateur d’une opération est le symbole qui désigne le calcul a faire avec les arguments qui l’entourent, il y a de nombreux opérateur, citons en quelque un:

+ , – , * , / , % , ! , & , ^ , >> , << , AND etc…

Une opération munie d’une seule opérande est appelé opération unaire, avec deux opérandes elle est appelée binaire et enfin (nous le verrons dans la session relatif aux instructions de contrôles) il existe des opérations à trois opérandes qu’on appelle opérations ternaire.

Opérateurs simplifié d’affectation

Si une variable se trouve dans l’opérande de gauche et dans l’une des deux opérandes de droite d’une affectation alors il est possible de faire une réécriture simplifiée de l’opération, par exemple:

a= a+5; peut être simplifiée par a+=5;

il ne faut pas uniquement deux opérandes à droites mais deux opérandes (et donc l’usage d’un seul opérateur mathématique) à la suite d’une simplification, un exemple tout bête serait le suivant:

a=2+5+6+a; se simplifie par a+=13;

voici quelques exemples de réécritures simplifiées:

Soit la déclaration suivante: int x=4; y=2;

x += y est équivalent à: x = x+y résultat: 6
x -= y est équivalent à: x = x-y résultat: 2
x *= y est équivalent à: x = x*y résultat: 8
x /= y est équivalent à: x = x/y résultat: 2
x%=y est équivalent à: x=x%y résultat: 0

Les opérateurs incrémentaux

Il s’agit d’une autre écriture de x+=1 et x-=1

Soit x=4;
x++ équivaut à l’incrémentation par 1 résultat: 5
++x équivaut à l’incrémentation par 1 résultat: 5
x– équivaut à la décrémentation par 1 résultat: 3
–x équivaut à la décrémentation par 1 résultat: 3

Simple non 🙂 maintenant voyons la différence entre x++ et ++x (ou x– et –x)

1èr cas x++

var x=1;
var y;
y=x++; // ici on réalise l’instruction puis on incrémente => y=1 et x=2

2ème cas –x

x=1;
y=++x; // ici on incrémente puis on réalise l’instruction => y=2 et x=2

Division et modulo

En arithmétique, la division euclidienne (dite aussi division) entière est une opération qui, à deux entiers naturels appelés dividende et diviseur, associe deux entiers appelés quotient et reste. Selon le format: Dividende=diviseur * quotient + Reste: Dividende=diviseur * quotient + Reste.

Par exemple: 36=7*4+8

Le signe / représente la division et le signe % représente le modulo (reste de la division Euclidienne)

dans l’exemple précédent 8 qui est le reste représente le résultat de dividende [modulo] (diviseur*quotient)

Soit D=dq+r
Si le reste (r) est nul on dit que D (dividende) est divisible par d (diviseur) ou que d est un diviseur de a

Soit le code suivant:

main(){
int x=4,y=3;
print (x/y);
print (x%y);
}

cela nous affichera:

1.3333333333333333
1
Remarque: le modulo est une fonction très importante en informatique (nous l’utiliserons dans la session relative aux dates), elle peut être décrite comme suit:
x % y = x – y * (x/y).floor()
Oops floor??? Dance floor?? c’est quoi 🙂 et bien nous allons le voir de suite

Les fonctions mathématiques basiques ABS, ROUND, CEIL, FLOOR et TRUNCATE

  • La fonction abs rend la valeur absolue ce qui reviens en gros a enlever le signe « – » s’il existe. En langage mathématique cela correspond à « x » si x est positif et « -x » si x est négatif

// -4 -> 4 , 5 -> 5
print (a.abs());
print (bb.abs());

  • La fonction round arrondi à la valeur inférieur si le nombre après la virgule est strictement inférieur à 0.5 et arrondi à la valeur supérieur si le nombre après la virgule et supérieur ou égale à 0.5

// 4.3 -> 4 , 4.5 -> 5 , 4.9 -> 5 , -1.51 -> -2
// -1.49 -> -1 , -1.50 -> -1 , -1.51 -> -2
print (pi.round());

  • La fonction ceil donne un arrondissement toujours à la valeur supérieure

// -4.3 -> -4 , 4.3 -> 5 , -1.50 -> -1
print (pi.ceil());

  • La fonction floor renvoie la valeur inférieure

// -4.3 -> -5 , 4.3 -> 4 , -1.50 -> -2
print (pi.floor());

  • La fonction truncate quant a elle renvoie la valeur sans la partie après la virgule

// -1.49 -> -1 , 1.50 -> 1
print (pi.truncate());

Les constantes mathématiques

Les constantes sont des valeurs qu’on dit remarquables, elle existe dans tous les domaines, théorie des nombres, théorie de l’information, en analyse, en combinatoire, en physique …

Vous pouvez très facilement définir une constante sur Dart grâce au type final (Voir Session 01).

print(Math.E); // Nombre d’Euler
print(Math.LN10); // logarithme de 10 équivalent à Math.log(10.0)
print(Math.LN2); // logarithme de 2 équivalent à Math.log(2.0)
print(Math.LOG2E); // Base 2 du logarithme de E (Nombre d’Euler)
print(Math.LOG10E); // Base 10 du logarithme de E (Nombre d’Euler)
print(Math.PI); // valeur de Pi 3.141592
print(Math.SQRT1_2);// Racine carrée de 0.5 (1/2)
print(Math.SQRT2); // Racine carrée de 2

Tester le code

un mot sur le nombre d’Euler

print(Math.exp(1)); // Renvoie E (2.718281)
print(Math.log(Math.E)); // Renvoie 1

print (Math.exp(Math.LN10)); // Renvoie 10.000000000000002
print (Math.exp(Math.LN2)); // Renvoie 2
// déclaration d’une valeur epsilon
final double EPSILON = 1e-10;

Valeur Maximale et valeur minimale

// renvoie la valeur maximale
print (Math.max(a,b));
// renvoie la valeur minimale
print (Math.min(a,b));

La fonction random « récupérer » un nombre au hasard 🙂

La fonction random renvoie un nombre au hasard entre 0 et 1.

print (Math.random());

Pour le renvoi d’un nombre au hasard entre 0 et 10 on peut faire ceci

print ((Math.random()*10).truncate());

La puissance (waw !)et la Racine carrée

  • Les Puissances:

print (Math.pow(4,2)); // affiche 4 au carré (soit 16)
print (Math.pow(4,3)); // affiche le résultat de 4 à la puissance 3 (soit 64)

  • Les Racines carrée

print (Math.sqrt(16)); // retourne 4
print (Math.sqrt(64)); // retourne 8
print (Math.sqrt(-64)); // retourne NaN, comme dans beaucoup de langage Nan veut dire que le résultat retourné n’est pas un nombre (Not a Number )

Les fonctions trigonométriques

Sachez que les fonctions trigonométriques cosinus,sinus,tangente,arc cosinus arc sinus arc tangente prennent comme argument une valeur en radian et non en degré

  • Relation entre le degré et le radian

 1 degre = 0,0174532925199 radian
1 degre = radian * Math.PI / 180 => var radian = angle * Math.PI / 180

  • Les fonctions trigonométrique

print (Math.cos(90));
print (Math.cos(90));
print (Math.sin(90));
print (Math.tan(90));
print (Math.acos(90)); //  NaN (Not A Number)
print (Math.asin(90)); // NaN (Not A Number)
print (Math.acos(0.4));
print (Math.asin(0.4));
print (Math.atan(90));
print (Math.atan2(90,45));

Les tests

  • Tester le signe avec isNegative()

num nombre=-1.5;
String resultat= »positive »;
if (nombre.isNegative())resultat= »negative »;
print (« le nombre $nombre est $resultat »);

  • Tester la parité avec odd() & even()

for (var i=0; i <10; i++) if (i.isEven()) print(i);
for (var i=0; i <10; i++) if (i.isOdd()) print(i);

  • Tester si le résultat n’est pas un numérique NaN

if(Math.acos(90).isNaN()) print (« Attention le résultat n’est pas un nombre »);
if(Math.cos(90).isNaN()) print (« Attention le résultat n’est pas un nombre »); else print (« Pas de NaN détécté »);
var testNan = « Excalibur 🙂 »;
if(Math.pow(testNan,3).isNaN()) print (« Attention le résultat n’est pas un nombre »);

  • Tester si un nombre est infini, quand le nombre est supérieur à 1.7976931348623157E+10308. (positif ou négatif)

var division=Math.parseInt(« 1 »)/Math.parseInt(« 0 »);
if (division.isInfinite()) print (« Résultat Infini! »);
division=Math.parseDouble(« 1 »)/Math.parseDouble(« 0 »);
if (division.isInfinite()) print (« Résultat Infini! »);

  • Un mot sur parseInt, parseDouble et Expect.equals
  1. La fonction Expect.equals « Expect.equals(a,b)  » est un test qui verifie que le résultat de l’expression B donne A, si c’est faux il retourne une alerte, sinon il ne fait rien. Par exemple: Expect.equals(8, 4+5); retournera le message d’erreur suivant: Expect.equals(expected: <8>, actual: <9>) fails.
  2. La fonction ParseInt permet de convertir une chaine en un entier int (ou « NaN » [Not a Number] si c’est impossible)
  3. La fonction ParseDouble permet de convertir une chaine en un décimal (ou « NaN » si c’est impossible)

Expect.equals(0, Math.parseInt(« 0 »));
Expect.equals(0, Math.parseInt(« +0 »));
Expect.equals(0, Math.parseInt(« -0″));
Expect.equals(0, Math.parseInt( » 0 « ));
Expect.equals(0, Math.parseInt( » +0 « ));
Expect.equals(0, Math.parseInt( » -0 « ));
Expect.equals(10, Math.parseInt(« 010 »));
Expect.equals(-10, Math.parseInt(« -010″));
Expect.equals(10, Math.parseInt( » 010 « ));
Expect.equals(-10, Math.parseInt( » -010 « ));

Expect.equals(499.0, Math.parseDouble(« 499 »));
Expect.equals(499.0, Math.parseDouble(« 499.0 »));
Expect.equals(499.0, Math.parseDouble(« 499.0 »));
Expect.equals(499.0, Math.parseDouble(« +499 »));
Expect.equals(-499.0, Math.parseDouble(« -499″));
Expect.equals(499.0, Math.parseDouble( » 499 « ));
Expect.equals(499.0, Math.parseDouble( » +499 « ));
Expect.equals(-499.0, Math.parseDouble( » -499 « ));
Expect.equals(0.0, Math.parseDouble(« 0 »));
Expect.equals(0.0, Math.parseDouble(« +0 »));
Expect.equals(-0.0, Math.parseDouble(« -0 »));
Expect.equals(true, Math.parseDouble(« -0″).isNegative());
Expect.equals(0.0, Math.parseDouble( » 0 « ));
Expect.equals(0.0, Math.parseDouble( » +0 « ));
Expect.equals(-0.0, Math.parseDouble( » -0 « ));
Expect.equals(10.0, Math.parseDouble(« 010 »));
Expect.equals(-10.0, Math.parseDouble(« -010″));
Expect.equals(10.0, Math.parseDouble( » 010 « ));
Expect.equals(-10.0, Math.parseDouble( » -010 « ));
Expect.equals(0.1, Math.parseDouble(« 0.1″));
Expect.equals(0.1, Math.parseDouble( » 0.1 « ));
Expect.equals(0.1, Math.parseDouble( » +0.1 « ));
Expect.equals(-0.1, Math.parseDouble( » -0.1 « ));
Expect.equals(0.1, Math.parseDouble(« .1″));
Expect.equals(0.1, Math.parseDouble( » .1 « ));
Expect.equals(0.1, Math.parseDouble( » +.1 « ));
Expect.equals(-0.1, Math.parseDouble( » -.1 « ));
Expect.equals(1234567.89, Math.parseDouble(« 1234567.89″));
Expect.equals(1234567.89, Math.parseDouble( » 1234567.89 « ));
Expect.equals(1234567.89, Math.parseDouble( » +1234567.89 « ));
Expect.equals(-1234567.89, Math.parseDouble( » -1234567.89 « ));

Les opérations Binaires

On retrouve dans les opérations binaires, les opérations bits à bits tel que (!, &, |, ^), les opérateurs de décalages (>>, <<, >>>) et les opérateurs logiques (&&, ||)

  • La fonction AND 🙂 imaginez deux robinets l’un après l’autre, le robinet A et le robinet B, si A est fermé et B fermé il n’y a pas d’eau, Si A est ouvert et B fermé il n’y a pas d’eau (puisque B va couper l’arrivé), Si B est ouvert et A fermé même chose, par contre si A et B sont ouvert alors il y a de l’eau! et bien c’est la la fonction AND, deux robinet en série l’un après l’autre
Entrée Sortie
A B A ET B
0 0 0
0 1 0
1 0 0
1 1 1
  • La fonction OR c’est deux robinets en parallèle 😉 il suffit qu’un des deux robinet soit ouvert pour qu’on ai de l’eau
Entrée Sortie
A B A OU B
0 0 0
0 1 1
1 0 1
1 1 1
  • La fonction NOT inverse l’état de 0 à 1 et de 1 à zéro, si un robinets est ouvert il le ferme, s’il est fermé il l’ouvre :
Entrée Sortie
A NON A
0 1
1 0
  • Les fonctions NAND, NOR, XOR et XNOR

NAND:deux robinets en série, ici c’est vrai (valeur 1) si l’eau n’arrive pas donc si un des robinets est fermé donc si A ou B est à 0.

Entrée Sortie
A B A NAND B
0 0 1
0 1 1
1 0 1
1 1 0

NOR: deux robinets en parallèle, C’est N pour Non donc on veut que l’eau n’arrive pas (valeur 1) que si les deux robinet sont fermé (donc A et B sont égale à 0)

Entrée Sortie
A B A NOR B
0 0 1
0 1 0
1 0 0
1 1 0

XOR: Pour s’en rappeler dites vous qu’en gros si les robinets n’ont pas le même état alors la valeur est à 1 (avec plus d’éléments binaire c’est un peu plus compliqué)

Entrée Sortie
A B A XOR B
0 0 0
0 1 1
1 0 1
1 1 0

XNOR: L’inverse de XOR, si les deux robinets ont le même état (la même valeur) alors la sortie est un 1

Entrée Sortie
A B A XNOR B
0 0 1
0 1 0
1 0 0
1 1 1

Codage

print(2 & 5); // 2 en binaire c’est 0010 et 5 c’est 0101
// en lés mettant l’un en dessous de l’autre, aucun 1 l’un sous l’autre -> resultat 0
print(7 & 13);// 7 en binaire c’est 0111 et 13 c’est 1101, la fonction AND donne 00101 -> resultat 5
print(2 | 5); // 0010 OR 0101 donne 0111 (7)
print(7 | 13);// 0111 OR 1101 donne 1111 (15)
print(2 ^ 5); // 0010 XOR 0101 donne 0111 (7)
print(7 ^ 13);// 0111 XOR 1101 donne 1010 (10)
print(~9); // le resultat (sur 32 bits) négative veut dire qu’au lieu de lire avec des 1 lisez avec des zeros
// 00000000000000000000000000001001 – > 11111111111111111111111111110110
// donc sans faire de calcul -> print(~x); affichera -(x + 1)
print(~7);print(~16);print(~291); // on aura ici -8, -17 -292
print(7<<1); // on décale 7 (0000111) d’un cran vers la gauche ce qui donne 14 (0001110)
print(12>>1); // on décale 12 (00001100) d’un cran vers la droite ce qui donne 6 (000000110)
print(12>>2); // on décale 12 (00001100) de deux crans vers la droite ce qui donne 3 (000000011)
print(1>>1); // retourne 0! -> pas de boucle pour dire que ce qui sort lors du décalage est perdu

[Tester le code des fonctions et opérateurs présentés jusqu’ici]

Les conversions

Un nombre hexadécimal commence toujours par 0x, par exemple l’hexadécimal EF7 sera noté 0xef7

  • Convertir un hexadécimal en décimal

main(){
print(Math.parseInt(« 0xef7 »)); // affiche 3831

Remarque: l’octal est aujourd’hui abandonnée au profit de la base 16

  • convertir un décimal en hexadécimal

var nombre=3831;
print(nombre.toRadixString(16)); //ef7

// Sans passage par une variable
print((255).toRadixString(16));

Les conversions de systèmes et simplification (décimal et exponentiel)

  • Le nombre de chiffre après la virgule peut être fixé par la fonction toStringAsFixed()

// soit le nombre Pi
print(Math.PI); // retourne 3.141592653589793
print((Math.PI).toStringAsFixed(2)); // retourne 3.14
print((Math.PI).toStringAsFixed(3)); // retourne 3.142
print((16).toStringAsFixed(0)); // retourne 16
print((16).toStringAsFixed(1)); // retourne 16.0
print((16).toStringAsFixed(4)); // retourne 16.0000

  • La Précision ou nombre de chiffre affichés, ici que ce soit avant ou après la virgule on arrondi (fonction ceil) et on coupe

// imaginons le nombre 1607 et voyons l’utilité pour la division en millier

// print((1607).toStringAsPrecision(0)); // ne fonctionne pas => precision 0 out of range
print((1607).toStringAsPrecision(1)); // retourne 2e+3
print((1607).toStringAsPrecision(2)); // retourne 1.6e+3
print((1607).toStringAsPrecision(3)); // retourne 1.61e+3

// imaginons à présent un nombre inférieur à 1000 (par exemple 80) et voyons le résultat
print((80).toStringAsPrecision(1)); // retourne 8e+1
print((80).toStringAsPrecision(2)); // retourne 80
print((80).toStringAsPrecision(3)); // retourne 80.0

  • Forcer l’affichage de la précision avec ou sans exponentiel

// si on veut forcer l’affichage de l’exponentiel
print((80).toStringAsPrecision(2)); // ici cela affiche 80 (sans exponentiel)
print((80).toStringAsExponential(2)); // retourne 8.00e+1

La méthode remainder()

La fonction remainder est l’équivalent de l’opérateur modulo « % »

// Modulo ou reste de la division peut être notée de deux facons
print(1%5);
print((1).remainder(5));
print(2%5);
print((2).remainder(5));
print(3%5);
print((3).remainder(5));
print(4%5);
print((4).remainder(5));
print(5%5);
print((5).remainder(5));
print(6%5);
print((6).remainder(5));
print(7%5);
print((7).remainder(5));

print(216%5);
print((216).remainder(5));

Un marge d’erreur à prendre en compte

Pour revenir aux fonctions trigonométrique, nous avions précisé que celles ci utilisent le radian qui peut être obtenu a partir du degré en multipliant par Pi et divisant par 180 or Pi transcendant et surtout irrationnel. La conversion et conversion iverse ne donnera pas le même résultat et causera une marge d’erreur. par exemple cosinus de 90° est égale à 0 or: print(Math.cos((90*Math.PI)/180));  // Dart retourne 6.123233995736766e-17 🙂
En java il existe les fonctions Math.toRadians(x) and Math.toDegrees(x) qui permettent de convertir d’une unité de mesure radian vers l’unité degrée et vice et versa. Seulement elle n’est pas « encore? » implémentée dans Dart. Qui sait ce que l’équipe de développement nous réserve? Nous observons déja des améliorations du DartBoard depuis la mise en ligne de la session 1 qui se voit rajouter un case à coché permettant d’activer la compilation avec l’option « –enable_type_checks »

[Tester le code]

La suite des sessions …

Dans cette partie nous avons fait un tour sur toutes les fonctions mathématiques disponible à la Révision 1229 de Google Dart.

Dans nos prochaines sessions nous verrons les Structures de contrôles Dart, permettant ainsi de réaliser des véritables algorithmes, nous verrons ensuite la manipulation des chaines de caractères qui est tout aussi intéréssante et qui nous aidera à y voir mieux lors de la session sur les interfaces List<E>, Set<E> et Queue<E>,

Session 01 -Google Dart –  Les Bases

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s