From b00ec932fc27ee5d1f6f512d19a3c60a46f537d8 Mon Sep 17 00:00:00 2001 From: Sean Wheeler Date: Tue, 10 Dec 2024 14:36:46 -0600 Subject: [PATCH 1/2] Add clarifications from mklement0 (#11573) --- .../About/about_Type_Conversion.md | 45 ++++++++++++++++--- .../About/about_Type_Conversion.md | 45 ++++++++++++++++--- .../About/about_Type_Conversion.md | 45 ++++++++++++++++--- 3 files changed, 117 insertions(+), 18 deletions(-) diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md index 5e32e3f2badd..e14506d5c38d 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md @@ -1,7 +1,7 @@ --- description: Describes how and when PowerShell performs type conversions. Locale: en-US -ms.date: 12/05/2024 +ms.date: 12/10/2024 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_type_conversion?view=powershell-5.1&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Type_Conversion @@ -40,11 +40,11 @@ PS> $var.GetType().Name Int32 ``` -Type casting ensures that only values of the specified type can be assigned to -the variable. PowerShell performs an implicit conversion if you try to assign a -value of a different type that can be converted to the constrained type. For -more information, see the [Implicit type conversion][03] section of this -article. +Type constraining ensures that only values of the specified type can be +assigned to the variable. PowerShell performs an implicit conversion if you try +to assign a value of a different type that can be converted to the constrained +type. For more information, see the [Implicit type conversion][03] section of +this article. ### Numeric type conversion @@ -64,6 +64,21 @@ Byte The value `42.1` is a **Double**. When you cast it to a **Byte**, PowerShell truncates it to an integer `42`, which is small enough to fit into a **Byte**. +When converting real numbers to integer types, PowerShell uses rounding rather +than truncation, specifically using the _rounding-to-nearest-even_ method. +The following examples illustrate this behavior. Both values are rounded to the +nearest even integer, `22`. + +```powershell +PS> [byte]21.5 +22 +PS> [byte]22.5 +22 +``` + +For more information, see the _Midpoint values and rounding conventions_ +section of the [Math.Round][21] method. + ### Boolean type conversion A value of _any_ type can be coerced to a **Boolean**. @@ -385,6 +400,23 @@ Int64 The `L` suffix on the `1` literal forces the result to be an **Int64**. For more information, see [about_Numeric_Literals][07]. +Using the `L` suffix is the preferred approach because it avoids loss of +accuracy. If the type cast is applied after the calculation, you can lose +accuracy due to the late type conversion. In the following example, the result +is too large to fit into an **Int64** type so it is converted to a **Decimal**. + +```powershell +PS> '{0:N0}' -f ([Int64]::MaxValue + 1L) +9,223,372,036,854,775,808 +``` + +Type casting the result after the calculation results in a loss in precision. + +```powershell +PS> '{0:N0}' -f [decimal]([Int64]::MaxValue + 1) +9,223,372,036,854,780,000 +``` + Usually, the left-hand side (LHS) operand of PowerShell operators determines the data type used in the operation. PowerShell converts (coerces) the right-hand side (RHS) operand to the required type. @@ -490,3 +522,4 @@ For more information, see [about_Comparison_Operators][05]. [18]: xref:System.Management.Automation.PSTypeConverter [19]: xref:System.Math.DivRem* [20]: xref:System.Math.Truncate* +[21]: xref:System.Math.Round*#midpoint-values-and-rounding-conventions diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md index c7f0d5531e8f..30e0abdee868 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md @@ -1,7 +1,7 @@ --- description: Describes how and when PowerShell performs type conversions. Locale: en-US -ms.date: 12/05/2024 +ms.date: 12/10/2024 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_type_conversion?view=powershell-7.4&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Type_Conversion @@ -40,11 +40,11 @@ PS> $var.GetType().Name Int32 ``` -Type casting ensures that only values of the specified type can be assigned to -the variable. PowerShell performs an implicit conversion if you try to assign a -value of a different type that can be converted to the constrained type. For -more information, see the [Implicit type conversion][03] section of this -article. +Type constraining ensures that only values of the specified type can be +assigned to the variable. PowerShell performs an implicit conversion if you try +to assign a value of a different type that can be converted to the constrained +type. For more information, see the [Implicit type conversion][03] section of +this article. ### Numeric type conversion @@ -64,6 +64,21 @@ Byte The value `42.1` is a **Double**. When you cast it to a **Byte**, PowerShell truncates it to an integer `42`, which is small enough to fit into a **Byte**. +When converting real numbers to integer types, PowerShell uses rounding rather +than truncation, specifically using the _rounding-to-nearest-even_ method. +The following examples illustrate this behavior. Both values are rounded to the +nearest even integer, `22`. + +```powershell +PS> [byte]21.5 +22 +PS> [byte]22.5 +22 +``` + +For more information, see the _Midpoint values and rounding conventions_ +section of the [Math.Round][21] method. + ### Boolean type conversion A value of _any_ type can be coerced to a **Boolean**. @@ -385,6 +400,23 @@ Int64 The `L` suffix on the `1` literal forces the result to be an **Int64**. For more information, see [about_Numeric_Literals][07]. +Using the `L` suffix is the preferred approach because it avoids loss of +accuracy. If the type cast is applied after the calculation, you can lose +accuracy due to the late type conversion. In the following example, the result +is too large to fit into an **Int64** type so it is converted to a **Decimal**. + +```powershell +PS> '{0:N0}' -f ([Int64]::MaxValue + 1L) +9,223,372,036,854,775,808 +``` + +Type casting the result after the calculation results in a loss in precision. + +```powershell +PS> '{0:N0}' -f [decimal]([Int64]::MaxValue + 1) +9,223,372,036,854,780,000 +``` + Usually, the left-hand side (LHS) operand of PowerShell operators determines the data type used in the operation. PowerShell converts (coerces) the right-hand side (RHS) operand to the required type. @@ -490,3 +522,4 @@ For more information, see [about_Comparison_Operators][05]. [18]: xref:System.Management.Automation.PSTypeConverter [19]: xref:System.Math.DivRem* [20]: xref:System.Math.Truncate* +[21]: xref:System.Math.Round*#midpoint-values-and-rounding-conventions diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md index f66cf8bf139c..9aa9cc4aa727 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md @@ -1,7 +1,7 @@ --- description: Describes how and when PowerShell performs type conversions. Locale: en-US -ms.date: 12/05/2024 +ms.date: 12/10/2024 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_type_conversion?view=powershell-7.5&WT.mc_id=ps-gethelp schema: 2.0.0 title: about_Type_Conversion @@ -40,11 +40,11 @@ PS> $var.GetType().Name Int32 ``` -Type casting ensures that only values of the specified type can be assigned to -the variable. PowerShell performs an implicit conversion if you try to assign a -value of a different type that can be converted to the constrained type. For -more information, see the [Implicit type conversion][03] section of this -article. +Type constraining ensures that only values of the specified type can be +assigned to the variable. PowerShell performs an implicit conversion if you try +to assign a value of a different type that can be converted to the constrained +type. For more information, see the [Implicit type conversion][03] section of +this article. ### Numeric type conversion @@ -64,6 +64,21 @@ Byte The value `42.1` is a **Double**. When you cast it to a **Byte**, PowerShell truncates it to an integer `42`, which is small enough to fit into a **Byte**. +When converting real numbers to integer types, PowerShell uses rounding rather +than truncation, specifically using the _rounding-to-nearest-even_ method. +The following examples illustrate this behavior. Both values are rounded to the +nearest even integer, `22`. + +```powershell +PS> [byte]21.5 +22 +PS> [byte]22.5 +22 +``` + +For more information, see the _Midpoint values and rounding conventions_ +section of the [Math.Round][21] method. + ### Boolean type conversion A value of _any_ type can be coerced to a **Boolean**. @@ -385,6 +400,23 @@ Int64 The `L` suffix on the `1` literal forces the result to be an **Int64**. For more information, see [about_Numeric_Literals][07]. +Using the `L` suffix is the preferred approach because it avoids loss of +accuracy. If the type cast is applied after the calculation, you can lose +accuracy due to the late type conversion. In the following example, the result +is too large to fit into an **Int64** type so it is converted to a **Decimal**. + +```powershell +PS> '{0:N0}' -f ([Int64]::MaxValue + 1L) +9,223,372,036,854,775,808 +``` + +Type casting the result after the calculation results in a loss in precision. + +```powershell +PS> '{0:N0}' -f [decimal]([Int64]::MaxValue + 1) +9,223,372,036,854,780,000 +``` + Usually, the left-hand side (LHS) operand of PowerShell operators determines the data type used in the operation. PowerShell converts (coerces) the right-hand side (RHS) operand to the required type. @@ -490,3 +522,4 @@ For more information, see [about_Comparison_Operators][05]. [18]: xref:System.Management.Automation.PSTypeConverter [19]: xref:System.Math.DivRem* [20]: xref:System.Math.Truncate* +[21]: xref:System.Math.Round*#midpoint-values-and-rounding-conventions From f9bc7a4f503df7118b77c4a535f3855c21010773 Mon Sep 17 00:00:00 2001 From: Sean Wheeler Date: Tue, 10 Dec 2024 15:48:19 -0600 Subject: [PATCH 2/2] More updates (#11574) --- .../About/about_Type_Conversion.md | 21 ++++++++++++++----- .../About/about_Type_Conversion.md | 21 ++++++++++++++----- .../About/about_Type_Conversion.md | 21 ++++++++++++++----- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md index e14506d5c38d..b555521f7633 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Type_Conversion.md @@ -100,7 +100,7 @@ A value of _any_ type can be coerced to a **Boolean**. ``` - For other types, null values, empty strings, and empty arrays are converted - to `$false`. Other values, including empty hashtables convert to `$true`. + to `$false`. ```powershell PS> [boolean]'' @@ -109,7 +109,16 @@ A value of _any_ type can be coerced to a **Boolean**. False PS> [boolean]'Hello' True - PS> [boolean]@(1,'Hello') + ``` + + Other values, including empty hashtables convert to `$true`. Single-element + collections evaluate to the Boolean value of their one and only element. + Collections with more than 1 element are always `$true`. + + ```powershell + PS> [boolean]@(0) + False + PS> [boolean]@(0,0) True PS> [boolean]@{} True @@ -300,8 +309,9 @@ This common code pattern is an instance of _pseudo method syntax_, which doesn't always work as intended. This syntax translates to: ```powershell -[byte[]] $bytes = 1..16 -New-Object -TypeName System.Guid -ArgumentList $bytes # !! BROKEN +PS> [byte[]] $bytes = 1..16 +PS> New-Object -TypeName System.Guid -ArgumentList $bytes +New-Object: Cannot find an overload for "Guid" and the argument count: "16". ``` Given that the type of **ArgumentList** is `[object[]]`, a single argument that @@ -310,7 +320,8 @@ workaround is to wrap `$bytes` in an outer array so that PowerShell looks for a constructor with parameters that match the contents of the outer array. ```powershell -PS> $guid = New-Object System.Guid(@(, $bytes)) +PS> [byte[]] $bytes = 1..16 +PS> $guid = New-Object -TypeName System.Guid -ArgumentList (, $bytes) PS> $guid Guid diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md index 30e0abdee868..7dd49e24834a 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Type_Conversion.md @@ -100,7 +100,7 @@ A value of _any_ type can be coerced to a **Boolean**. ``` - For other types, null values, empty strings, and empty arrays are converted - to `$false`. Other values, including empty hashtables convert to `$true`. + to `$false`. ```powershell PS> [boolean]'' @@ -109,7 +109,16 @@ A value of _any_ type can be coerced to a **Boolean**. False PS> [boolean]'Hello' True - PS> [boolean]@(1,'Hello') + ``` + + Other values, including empty hashtables convert to `$true`. Single-element + collections evaluate to the Boolean value of their one and only element. + Collections with more than 1 element are always `$true`. + + ```powershell + PS> [boolean]@(0) + False + PS> [boolean]@(0,0) True PS> [boolean]@{} True @@ -300,8 +309,9 @@ This common code pattern is an instance of _pseudo method syntax_, which doesn't always work as intended. This syntax translates to: ```powershell -[byte[]] $bytes = 1..16 -New-Object -TypeName System.Guid -ArgumentList $bytes # !! BROKEN +PS> [byte[]] $bytes = 1..16 +PS> New-Object -TypeName System.Guid -ArgumentList $bytes +New-Object: Cannot find an overload for "Guid" and the argument count: "16". ``` Given that the type of **ArgumentList** is `[object[]]`, a single argument that @@ -310,7 +320,8 @@ workaround is to wrap `$bytes` in an outer array so that PowerShell looks for a constructor with parameters that match the contents of the outer array. ```powershell -PS> $guid = New-Object System.Guid(@(, $bytes)) +PS> [byte[]] $bytes = 1..16 +PS> $guid = New-Object -TypeName System.Guid -ArgumentList (, $bytes) PS> $guid Guid diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md index 9aa9cc4aa727..1d0e4a25c8f4 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Type_Conversion.md @@ -100,7 +100,7 @@ A value of _any_ type can be coerced to a **Boolean**. ``` - For other types, null values, empty strings, and empty arrays are converted - to `$false`. Other values, including empty hashtables convert to `$true`. + to `$false`. ```powershell PS> [boolean]'' @@ -109,7 +109,16 @@ A value of _any_ type can be coerced to a **Boolean**. False PS> [boolean]'Hello' True - PS> [boolean]@(1,'Hello') + ``` + + Other values, including empty hashtables convert to `$true`. Single-element + collections evaluate to the Boolean value of their one and only element. + Collections with more than 1 element are always `$true`. + + ```powershell + PS> [boolean]@(0) + False + PS> [boolean]@(0,0) True PS> [boolean]@{} True @@ -300,8 +309,9 @@ This common code pattern is an instance of _pseudo method syntax_, which doesn't always work as intended. This syntax translates to: ```powershell -[byte[]] $bytes = 1..16 -New-Object -TypeName System.Guid -ArgumentList $bytes # !! BROKEN +PS> [byte[]] $bytes = 1..16 +PS> New-Object -TypeName System.Guid -ArgumentList $bytes +New-Object: Cannot find an overload for "Guid" and the argument count: "16". ``` Given that the type of **ArgumentList** is `[object[]]`, a single argument that @@ -310,7 +320,8 @@ workaround is to wrap `$bytes` in an outer array so that PowerShell looks for a constructor with parameters that match the contents of the outer array. ```powershell -PS> $guid = New-Object System.Guid(@(, $bytes)) +PS> [byte[]] $bytes = 1..16 +PS> $guid = New-Object -TypeName System.Guid -ArgumentList (, $bytes) PS> $guid Guid