You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unlike with [decimal], however, the [bigint] behavior can be surprising, given that the result is invariably an integer, even with a [double] operand; for instance:
# Note: 1n is the same as [bigint] 1
1n *1.99# -> [bigint] 1
That is, the above is the equivalent of: [bigint] 1 * [bigint] 1.99, which is effectively the same as [bigint] 1 * [bigint] 1
As an aside: it seems that [bigint] casts, unlike casts with other integer types, never round, i.e. always truncate (e.g., [bigint] 1.99 is 1, whereas [int] 1.99 is 2)
The upshot is that you cannot perform fractional calculations with [bigint] operands; the only option is to downgrade to a [decimal] - assuming the value fits into the latter (e.g., [decimal] 1n * 1.99 yields [decimal] 1.99)
As an aside:
best expresses the result without losing precision.
Note that you can lose accuracy (precision) even in integer arithmetic, namely with either [int] or [long] operands that yield a result that doesn't fit into the respective type, because the result becomes a [double].
With small enough results that conceptually represent integers that is not a problem, but [double] can only accurately represent integers between -9007199254740992 and 9007199254740992 (-/+2 to the power of 53, which you can calculate with [bigint]::Pow(2, 53); see "Precision limits on integer values" on Wikipedia), which is way below the [long]::MinValue and [long]::MaxValue limits, -9223372036854775808 and 9223372036854775807.
Here's an example of perhaps unexpected loss of accuracy, based on a literal that has the value of [long]::MaxValue:
[ulong] (9223372036854775807+2)
This yields [ulong] 9223372036854775808, i.e. an inaccurate result: the last digit is 8, even though accurate integer arithmetic would yield 9. The reason is that 9223372036854775807 + 2 (a [long] + [int] calculation) - was coerced to [double] first.
Using [ulong] to begin with would avoid that problem (9223372036854775807ul + 2), but exceeding the range of [ulong] too would again result in a [double] (([ulong]::MaxValue + 1).GetType().Name)
Type of issue
Missing information
Feedback
The "Type conversion to accommodate result" section commendably already states:
The same applies to
[bigint]
(applies to Windows PowerShell too), which should be mentioned too - see:Unlike with
[decimal]
, however, the[bigint]
behavior can be surprising, given that the result is invariably an integer, even with a[double]
operand; for instance:That is, the above is the equivalent of:
[bigint] 1 * [bigint] 1.99
, which is effectively the same as[bigint] 1 * [bigint] 1
[bigint]
casts, unlike casts with other integer types, never round, i.e. always truncate (e.g.,[bigint] 1.99
is1
, whereas[int] 1.99
is2
)The upshot is that you cannot perform fractional calculations with
[bigint]
operands; the only option is to downgrade to a[decimal]
- assuming the value fits into the latter (e.g.,[decimal] 1n * 1.99
yields[decimal] 1.99
)As an aside:
Note that you can lose accuracy (precision) even in integer arithmetic, namely with either
[int]
or[long]
operands that yield a result that doesn't fit into the respective type, because the result becomes a[double]
.E.g.,
([int]::MaxValue + 1).GetType().Name
yields'Double'
.With small enough results that conceptually represent integers that is not a problem, but
[double]
can only accurately represent integers between-9007199254740992
and9007199254740992
(-/+2 to the power of 53, which you can calculate with[bigint]::Pow(2, 53)
; see "Precision limits on integer values" on Wikipedia), which is way below the[long]::MinValue
and[long]::MaxValue
limits,-9223372036854775808
and9223372036854775807
.Here's an example of perhaps unexpected loss of accuracy, based on a literal that has the value of
[long]::MaxValue
:This yields
[ulong] 9223372036854775808
, i.e. an inaccurate result: the last digit is8
, even though accurate integer arithmetic would yield9
. The reason is that9223372036854775807 + 2
(a[long] + [int]
calculation) - was coerced to[double]
first.Using
[ulong]
to begin with would avoid that problem (9223372036854775807ul + 2
), but exceeding the range of[ulong]
too would again result in a[double]
(([ulong]::MaxValue + 1).GetType().Name
)Page URL
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arithmetic_operators?view=powershell-7.4#type-conversion-to-accommodate-result
Content source URL
https://github.com/MicrosoftDocs/PowerShell-Docs/blob/main/reference/7.4/Microsoft.PowerShell.Core/About/about_Arithmetic_Operators.md
Author
@sdwheeler
Document Id
b9c71b38-8d48-1402-6d59-e394ac7a5468
The text was updated successfully, but these errors were encountered: