Affichage des articles dont le libellé est produit. Afficher tous les articles
Affichage des articles dont le libellé est produit. Afficher tous les articles

lundi 5 mars 2018

Effet de bord (variables) Démo

L'effet de bord (effet secondaire) pour les variables surgit lorsque la variable prend une valeur illogique. Cet effet peut figurer aussi avec les fonctions. (Pour un peu de détail : ici)

Pour les variables, la cause principale est la limite imposée par la taille de la variable.

Cet article vise à donner un exemple sur cet effet.

Démo

Pour démontrer cet effet, nous allons essayer de calculer le factoriel (n!) de quelques nombres. Cette fonction donne, rapidement, des valeurs très grandes.

En Pascal :

Program EffetDeBord;

Var
 i, factoriel : Integer;

Begin
 
 factoriel := 1;
 
 For i := 1 to 10 Do
 Begin
  factoriel := factoriel * i;
  WriteLn(i, '! = ', factoriel);
 End;
 
End.

L'exécution de ce code :



Nous pouvons voir que le calcul commence à donner des valeurs érronées et illogiques des (8!). En effet, le type Integer ne peut pas contenir des valeurs en dehors de l'intervalle : -32768 .. 32767.

Ce phénomène peut être réduit si on utilise des variables "plus grandes" comme le Longint (Long Integer) :


Program EffetDeBord;

Var
 i, factoriel : LongInt;

Begin
 
 factoriel := 1;
 
 For i := 1 to 10 Do
 Begin
  factoriel := factoriel * i;
  WriteLn(i, '! = ', factoriel);
 End;
 
End.

Ce code donne des valeurs plus correctes :


Un entier de type LongInt peut stocker des données de l'intervalle : -2147483648 .. 2147483647.

Pour plus d'information sur la taille des types de données, il faut consulter la documentation officielle du compilateur que vous utilisez. Par exemple :

Turbo Pascal : (ici
Free Pascal : (ici)

jeudi 16 novembre 2017

Le signe du produit sans le calculer : apprendre les conditions (expressions booléennes) compliquées

Énonce

Écrire un programme (un algorithme) qui demande deux nombres à l'utilisateur et l'informe si leur produit est positif, négatif ou bien nul sans le calculer.

L'objectif de cet exercice est une variété d'un autre exercice dans lequel on vérifie est ce qu'un nombre est positif, négatif ou bien nul. La différence ici est qu'on essaie de compliquer les conditions. Le reste de l'algorithme (la structure conditionnelle imbriquée) reste la même parce qu'il s'agit des mêmes cas (trois cas, exactement le même problème). A partir de l'analyse donnée dans le cadre de l'exercice précédent, il suffit de reprendre la partie concernant es conditions à vérifier :
  1. Le produit de a et b est positif si les deux nombres sont du même signe, c'est à dire, le produit est positif si et seulement si a et positif et b est positif ou bien a est négatif et b est négatif.
  2. Le produit de a et b est négatif si les deux nombres sont de signes différents, c''est à dire, le produit est négatif si a est positif et b est négatif ou bien a est négatif et b est positif.
  3. Le produit de a et b est nul s'il est ni positif, ni négatif.
Comme vous voyez, les conditions sont un peu plus complexes. En effet, cet exercice est lié aux expressions logiques (booléennes). Nous pouvons reprendre les définitions données telles qu'elle le sont; il suffit d'utiliser les bons symboles pour les opérations booléennes.
Ainsi, le programme sera :

En Pascal :

Program PositifNegatifNul;
Var
 a, b : Integer;
Begin
 WriteLn('Donnez deux nombres :');
 ReadLn(a);
 ReadLn(b);
 If (((a > 0) And (b > 0))  Or ((a < 0) And (b < 0))) Then 
  WriteLn('Le produit est Positif')
 Else
  if (((a < 0) And (b > 0))  Or ((a > 0) And (b < 0))) Then
   WriteLn('Le produit est Negatif')
  Else
   WriteLn('Le produit est Nul');
End.

En Java :


import java.util.Scanner;

public class Exemple {
 public static void main(String[] args) {
  Scanner scanner = new Scanner(System.in);
  System.out.println("Donnez deux nombres :");
  int a = scanner.nextInt();
  int b = scanner.nextInt();
  if(a < 0 && b < 0 || a > 0 && b > 0)
   System.out.println("Le produit est Positif"); 
  else
   if (a < 0 && b > 0 || a > 0 && b < 0)
    System.out.println("Le produit est Negatif"); 
   else
    System.out.println("Le produit est Nul"); 
 }
}



jeudi 9 novembre 2017

Calculs simples (partie 2)

Ennoncé de l'exercice :

Ecrire l'algorithme qui permet de calculer la somme, la différence et le produit de deux nombres entiers.

Solution (partie 2):

Nous avons vu dans la première partie, le programme qui permet de calculer la somme, la différence et le produit de deux nombres entiers. Néanmoins, nous avons codé directement les valeurs; tout changement des valeurs nécessitera de modifier le code et de le re-compiler. C'est trop pénible. Alors comment faire pour permettre au programme de récupérer à chaque fois de nouvelles valeurs sans devoir le modifier à chaque fois ?

Cela peut être fait en deux étapes :

La première étape : l'utilisation des variables :

Tout comme en mathématiques, il est possible de définir des variables, un symbole défini sur un ensemble donné et qui peut contenir UNE seule valeur A LA FOIS de cet ensemble. Cette valeur peut changer dans le temps, mais, à un instant donné t, cette valeur est unique.

En effet, si je définit la variable x ∈ N, cela veut dire que x prend sa valeur dans l'ensemble des nombres naturels N, mais il ne prendra qu'une seule valeur à la fois. Une telle déclaration en Pascal sera :


x : Integer;

Et en Java :

int x;

L'ordre peut changer entre les deux langages (symbole de la variable en premier ou bien son type) et même le nom du domaine (entre Integer en Pascal et int "seulement" en Java), néanmoins, l'idée et l'effet des deux déclaration sont exactement les mêmes.
En ajoutant les déclarations à nos codes, nous allons obtenir en Pascal :


Program FaireCalculs;
Var
 a, b, r1, r2, r3 : Integer;
Begin
 a := 5;
 b := 3;

 r1 := a + b;
 r2 := a - b;
 r3 := a * b;

 WriteLn(r1);
 WriteLn(r2);
 WriteLn(r3);
End.

Et en Java :

public class Exemple {
 public static void main(String[] args){
  int a, b, r1, r2, r3;
  
  a = 5;
  b = 3;

  r1 = a + b;
  r2 = a - b;
  r2 = a * b;

  System.out.println(r1);
  System.out.println(r2);
  System.out.println(r3);
 }
}

En utilisant ces variables, nous avons obtenu deux avantages :
  1. Il est maintenant possible de gagner du temps en ne modifiant que les valeurs de a et b (deux valeurs seulement) pour obtenir de nouveaux résultats.
  2. Nous avons séparé le calcul de l'affichage. En effet, les deux actions sont exécutées par des instructions séparées. Cela rend le code plus lisible et plus compréhensible.
Note : Les trois variables r1, r2 er r3 vont occuper 12 octets de votre RAM qui dépasse (probablement) 4 Go (4.294.967.296 octets); alors mettez vous à l'aise et déclarez autant de variables que vous voulez.

La deuxième étape : lecture à partir du clavier :

Si l'écran est la "sortie" principale de l'ordinateur, c'est à dire, le moyen principal qu'il utilise pour nous parler, le clavier est son "entrée" principale c'est à dire, le moyen principal que nous utilisons pour parler à l'ordinateur.

Nous avons déjà demandé à notre programme de nous parler. Nous avons demandé qu'il nous "affiche" quelque chose, certainement, sur sa sortie principale. L'ordre était différent entre les deux langages mais avec le même sens :
En Pascal :

WriteLn();  

En Java :


System.out.println();

Si on ignore la partie "ln" pour le moment, nous auront "write" et "print", au sens de "afficher" les données. Suivant la même idée, nous pouvons demander au programme de recevoir des données de notre part. Pour cela, nous utilisons son entrée principale, c'est à dire le clavier, pour lui parler.

En Pascal : très simple, il arrive à reconnaitre le type de la donnée passée en entrée.


ReadLn(a); {Lire la donnée "a"}

En Java : un peu plus complexe, parce qu'il ne reconnaît pas le type de la donnée, c'est à nous de lui préciser qu'est ce qu'il doit recevoir :


Scanner scanner = new Scanner(System.in); // Ecouter le clavier
a = scanner.nextInt(); // Lire l'entier suivant et le mettre dans la donnée "a"

En intégrant ces notions dans le code précédent, nous aurons le code Pascal :


Program FaireCalcul;
Var
 a, b, r1, r2, r3 : Integer;
Begin
 ReadLn(a);
 ReadLn(b);

 r1 := a + b;
 r2 := a - b;
 r3 := a * b;

 WriteLn(r1);
 WriteLn(r2);
 WriteLn(r3);
End.

Et en Java :


import java.util.Scanner;

public class Exemple {
 public static void main(String[] args){
  int a, b, r1, r2, r3;
  
  Scanner scanner = new Scanner(System.in);  
  a = scanner.nextInt();
  b = scanner.nextInt();

  r1 = a + b;
  r2 = a - b;
  r3 = a * b;

  System.out.println(r1);
  System.out.println(r2);
  System.out.println(r3);
 }
}

A ce stade, notre programme ne définit pas des valeur fixes; il les captent à partir du clavier (c'est l'utilisateur qui les saisit), par conséquent, nous pouvons calculer la somme, la différence et le produit autant de fois que nous voulons et avec de nouvelles valeurs à chaque fois sans avoir à modifier et re-compiler notre programme.

Calculs simples (partie 1)

Énoncé de l'exercice :

Ecrire l'algorithme qui permet de calculer la somme, la différence et le produit de deux nombres entiers.

Solution :


Cet exercice est parmi les premiers exercices à résoudre, il y a pas plus simple mais s'il s'agit du premier exercice de votre vie, alors des explications supplémentaires peuvent être données.

Tout comme en mathématiques, le produit, la différence et le produit prennent deux opérandes; l'opérateur prend sa place entre les deux. Ainsi, Une première idée qui viens en esprit sera le code Pascal suivant :


Program FaireCalculs;
Begin
 5 + 3;
 5 - 3;
 5 * 3;
End.

En Java :


public class Exemple {
 public static void main(String[] args){
  5 + 3;
  5 - 3;
  5 * 3;
 }
}

Mais, ce code est incorrect; faire un calcul sans garder le résultat et sans l'utiliser n'a aucun sens. Mais pourquoi le programme ne l'a pas affiché tout simplement ? Il ne l'a pas affiché parce que nous ne l'avons pas demandé, nous avons mis les opérations seulement. Pour "afficher" le résultat du calcul, il faut le demander explicitement. Ainsi, le programme qui fait le calcul et l'affiche sera en Pascal :


Program FaireCalculs; 
Begin
 WriteLn(5 + 3);
 WriteLn(5 - 3);
 WriteLn(5 * 3);
End.

Et en Java :


public class Exemple {
 public static void main(String[] args){
  System.out.println(5 + 3);
  System.out.println(5 - 3);
  System.out.println(5 * 3);
 }
}

(partie 2)