PS KOANS Walkthrougt

Exercice 3 « Basic Number Types » :

Dans Powershell un nombre peut être représenter par un type de donnée, par exemple, on peut de déclarer comme nombre entier, nombre décimal…
le choix du type dépendant des besoins spécifiques du script que l’on souhaite mettre en place.

  • Les entiers (Integers) : Les entiers représentent des nombres complets, sans fraction. Il s’agit du type numérique par défaut que PowerShell attribue aux nombres n’incluant pas de portion décimale. Ce type est privilégié pour les opérations nécessitant une précision absolue dans le comptage ou l’indexation, où les fractions n’ont pas leur place.
  • Les nombres à virgule flottante double précision (Doubles) : Les doubles sont utilisés pour représenter des nombres comportant des décimales ou des exposants. PowerShell sélectionne ce type numérique par défaut pour les nombres saisis avec des décimales ou des exposants, comme par exemple 0.5 ou 2e3 (qui représente 2 x 10^3, soit 2000). Cette catégorie est idéale pour les calculs nécessitant une grande précision sur les fractions ou lorsqu’il est question de manipuler des grandeurs scientifiques.

Powershell offre la possibilité de faire des opérations arithmétiques avec des types de nombres différents, à titre d’exemple, une addition d’un Integer avec un Double. Dans ce cas PowerShell procède automatiquement à la conversion du type le moins précis ou le plus étroit vers le type le plus précis ou le plus « grand ».

  • Opération entre un entier et un double :
    Si vous avez un entier 10 et que vous effectuez une opération arithmétique avec un double 0.5, PowerShell convertira automatiquement l’entier 10 en double avant de réaliser l’opération. Le résultat sera traité comme un double, par exemple, 10 + 0.5 donnera 10.5.
  • Opération entre un entier et un nombre à grande échelle (Bigint) :
    Lorsqu’une opération est réalisée entre un entier et un Bigint (un type conçu pour stocker de très grands nombres), l’entier est converti en Bigint.
    Par exemple, si on additionne un entier 2 avec un Bigint représentant le nombre 10000000000000000000, l’entier 2 est converti en Bigint avant l’addition.

A noter que Powershell intérprete automatiquement les types de nombres lorsqu’ils ne sont pas déclarer explicitement, ainsi, le nombre 10 sera interprété comme un entier et 10.0 comme un double, à moins qu’un type spécifique ne soit explicitement appliqué, soit par l’utilisation d’un suffixe de type, soit par un cast (conversion de type).

L’exemple suivant démontre comment déclarer un entier qui à l’air d’un Double (Double au sens Float) :
[int]$number = 10.0
Et dans cet exemple on utilise le suffix pour déclarer que le contenur de la variable $nombreDouble = 10D
Le D est le suffix, qui indique que le nombre doit être traité comme un Double.

Mais il existe une façon plus simple, et franchement plus explicite, qui consiste à utiliser le .NET pour déclarer les types :
[System.Int32]$integerVariable = 123
On vient de déclarer que le nombre contenu dans la variable $integerVariable est un entier (int32).

L’exercice suivant met en lumière certaines des différences fondamentales entre les types numériques.

Describe 'Basic Number Types' {

    Context 'Double' {

        It 'can result from an operation involving multiple types of numbers' {
            <#
                When doing arithmetic on different types of numbers, PowerShell
                will automatically convert the less precise or more narrow type
                to the other kind.
            #>
            $Int = 10
            $Double = 10.0

            #Le type de la variable $Int est un entier, alors la réponse c'est 'System.int32'
            'System.Int32' | Should -Be $Int.GetType().Fullname
            #Le type de la variable $Double est un Double, alors la réponse c'est 'System.Double'
            'System.Double' | Should -Be $Double.GetType().Fullname

            $Result = $Int * $Double

            #Question : What type results when you multiply integers and doubles?
            #Réponse : Comme on a dit que Powershell fait une conversion automatique du moins précis au plus précis, le résultat de la multiplication sera donc un Double, puisqu'il est plus précis que Integer
            'System.Double' | Should -Be $Result.GetType().Fullname
        }
    }

# La fonction Get-Number prend comme paramètre $Number, déclaré en tant qu'entier, Mandatory est déclaré pour rendre le paramètre obligatoire, si on ne l'écris pas, il affichera un message d'erreur 

#Deuxième réponse : 
    Context 'Integers' {

        It 'has to be a whole number' {
            function Get-Number {
                param(
                    [Parameter(Mandatory)]
                    [int]
                    $Number
                )
                $Number
            }
            #Cette ligne affecte le nombre Pi à la variable $Pi
            $Pi = [Math]::PI

#Réponse : 'System.Double', étant donnée que Pi est un chiffre a virgule, il sera donc reconnu comme Double, le résultat sera certaine un Double.
            'System.Double' | Should -be $Pi.GetType().Fullname

#Question : What number will return if you pass Pi into an int function?
#Réponse : On envois le résultat de $Pi qui est de type Double dans la fonction Get-Number qui va le transformer en Integer. Le résultat est 3, puisqu'il sera arrondi au plus proche (pi = 3,14, alors il sera arrondi à 3)
            3 | Should -Be (Get-Number -Number $Pi)
        }



        It 'can be a larger number if needed' {
            <#
                Integers come in two flavours:
                - int (Int32)
                - long (Int64)

                If an integer value exceeds the limits of the Int32 type, it is
                automatically expanded to the larger Int64 type.
            #>

            # What exactly are the limitations of the [int] type?
            $MaxValue = [int]::MaxValue
            $MinValue = [int]::MinValue

<#Réponse : $MaxValue, c'est la valeur maximum qu'un int32 peut prendre et elle est de 2147483647$ 
            $MinValue, c'est la valeur "minimum" qu'un int32 peut prendre, et elle est de -2147483648
            - C'est troublant, mais déjà pourquoi ca ne fait -2147483648 / 2147483648, c'est parceque le Zéro est 
            comptabilisé dans le compte
            - Pour le $MinValue, c'est la valeur négative maximum qu'un int32 peut prendre.
#>
     
            2147483647 | Should -Be $MaxValue
            -2147483648 | Should -Be $MinValue

<# Réponse : La valeur m

#>
            # If you enter a number larger than that, the type should change.
            $BigValue = 2147483648
            $BigValue | Should -BeOfType [long]
            $BigValue | Should -BeGreaterThan $MaxValue

            $SmallValue = -2147483649
            $SmallValue | Should -BeOfType [long]
            $SmallValue | Should -BeLessThan $MinValue
        }

        It 'allows you to request the larger type with a suffix' {
            <#
                By specifying the L suffix, a number is forced to use the long
                type. here are more suffixes available, depending on your
                PowerShell version. We'll cover those in a later topic.
            #>

            100L | Should -BeOfType [long]

            $Value = 100L
            $Value | Should -BeOfType [long]
            [int]::MinValue -le $Value -and $Value -le [int]::MaxValue | Should -BeTrue
        }
    }
}

Describe "Banker's Rounding" {
    <#
        The default midpoint rounding method used in PowerShell is called
        "Rounding to Even," or "Banker's Rounding". Numbers will be rounded to
        the nearest even integer when rounding from a midpoint (###.5) value.

        This behaviour stems from the underlying library method [math]::Round()
        which is documented in more detail here:
        https://docs.microsoft.com/en-us/dotnet/api/system.math.round#midpoint-values-and-rounding-conventions

        Alternate overloads of the Round() method are also available if you need
        to adjust the midpoint rounding method used for a particular use case.
    #>
#Pour l'arrondi, lorsqu'il est en mode int et que le Double est un parfait milieu (2.5) par exemple, il arrondi au plus petit. Contrairement au mode long, qui arrond au plus grand.
    It 'rounds to the nearest even when cast to integer if it is a midpoint' {
        # How will these numbers be rounded to integer?
        2 | Should -Be ([int]2.5)
        3 | Should -Be ([int]3.34)
        13 | Should -Be ([int]12.7)

        11 | Should -Be ([long]10.61)
        6 | Should -Be ([long]5.5)
    }
}

Dans powershell les entiers sont catagorisés en deux familles :
– int (Int32)
– long (Int64)
Si un int32 dépasse sa valeur maximal, il sera automatiquement convertit en int64.

A retenir :

L’arrondi pour les chiffres n’est pas identique lorsqu’il s’agit d’un nombre de type int ou long, l’int est arrondi a l’inférieu lorsqu’il est au ‘milieu’, contrairement au long qui arrondi au supérieur .

Retour en haut