Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify that a [bigint] operand in an arithmetic operation forces the other operand to [bigint] too #11004

Closed
mklement0 opened this issue Apr 4, 2024 · 0 comments · Fixed by #11007
Assignees
Labels
area-about Area - About_ topics

Comments

@mklement0
Copy link
Contributor

Type of issue

Missing information

Feedback

The "Type conversion to accommodate result" section commendably already states:

The System.Decimal type is an exception. If either operand has the Decimal type, the result is Decimal type.

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:

# 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].

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 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)

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

@mklement0 mklement0 added the needs-triage Waiting - Needs triage label Apr 4, 2024
@sdwheeler sdwheeler self-assigned this Apr 5, 2024
@sdwheeler sdwheeler added area-about Area - About_ topics and removed needs-triage Waiting - Needs triage labels Apr 5, 2024
sdwheeler added a commit that referenced this issue Apr 5, 2024
* Document the behavior of bigint math

* fix typo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-about Area - About_ topics
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants