gpt4 book ai didi

c# - PowerShell 和 C# 中的 BigInt 不一致

转载 作者:行者123 更新时间:2023-12-02 22:09:31 27 4
gpt4 key购买 nike

根据 microsoft documentation [BigInt]数据类型好像没有定义的最大值,理论上可以容纳无限大的数,但是我发现在第28位之后,开始出现一些奇怪的事情:

PS C:\Users\Neko> [BigInt]9999999999999999999999999999
9999999999999999999999999999
PS C:\Users\Neko> [BigInt]99999999999999999999999999999
99999999999999991433150857216
如您所见,在第一个命令 1 上, BigInt按预期工作,但多一位数字,似乎在翻译 99999999999999999999999999999 的地方发生了一些衰减。至 99999999999999991433150857216但是,提示不会抛出任何错误,您可以继续添加更多数字,直到第 310 位
PS C:\Users\Neko> [BigInt]99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336
PS C:\Users\Neko\> [BigInt]999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
这将抛出错误
At line:1 char:318
+ ... 999999999999999999999999999999999999999999999999999999999999999999999
+ ~
The numeric constant 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 is not valid.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : BadNumericConstant
我认为这是控制台问题而不是 BigInt问题是因为错误没有提到 [BigInt]数据类型不同于对于其他数据类型来说太大的数字,例如
PS C:\Users\Neko> [UInt64]18446744073709551615
18446744073709551615
PS C:\Users\Neko> [UInt64]18446744073709551616
Cannot convert value "18446744073709551616" to type "System.UInt64". Error: "Value was either too large or too small
for a UInt64."
At line:1 char:1
+ [UInt64]18446744073709551616
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastIConvertible
至于 C#, System.Numerics.BigInt将在第 20 位开始抛出错误, 99999999999999999999硬编码时:
namespace Test
{
class Test
{
static void Main()
{
System.Numerics.BigInteger TestInput;
System.Numerics.BigInteger Test = 99999999999999999999;
System.Console.WriteLine(Test);
}
}
}
尝试在 Visual Studio 中构建时出现错误
Integral constant is too large
但是,我可以输入更大的数字到 ReadLine不会导致错误
namespace Test
{
class Test
{
static void Main()
{
System.Numerics.BigInteger TestInput;
TestInput = System.Numerics.BigInteger.Parse(System.Console.ReadLine());
System.Console.WriteLine(TestInput);
}
}
}
这似乎确实是无限的。输入
99999999999...
(共 24720 个字符)工作正常2
那么是什么导致了 [BigInt] 所有这些奇怪的事件? ?

1 根据 ([Char[]]"$([BigInt]9999999999999999999999999999)").count 是 28 位数字
2 我懒得计算数字,试图将数字解析到 PowerShell 中会导致错误。根据 this它是 24720 个字符

最佳答案

TLDR : 使用 [BigInt]::Parse'literal' Powershell Core 7.0 之前的语法;否则使用 n后缀。
问题 - double文字
当涉及到无后缀的文字时,Powershell 将使用值适合的第一种类型。整数文字的顺序是 int , long , decimal然后 double .来自 documentation对于 Powershell 5.1(我的粗体;本段与 Powershell Core 相同):

For an integer literal with no type suffix:

  • If the value can be represented by type [int], that is its type.
  • Otherwise, if the value can be represented by type [long], that is its type.
  • Otherwise, if the value can be represented by type [decimal], that is its type.
  • Otherwise, it is represented by type [double].

在您的情况下,该值超过了 decimal.MaxValue所以你的文字默认是 double文字。那个 double value 不是完全可表示的,而是“转换”为最接近的可表示 double 值。
$h = [double]99999999999999999999999999999
"{0:G29}" -f $h
输出
99999999999999991000000000000
显然,这不是确切的数字,只是字符串形式的表示。但它让你知道发生了什么。现在我们采用这个不精确的 double值,我们将其转换为 BigInt .原始精度损失由转换运算符转移并复合。这就是 Powershell 中实际发生的事情(注意转换为 BigInt ):
$h = [BigInt][double]99999999999999999999999999999
"{0:G}" -f $h
输出
99999999999999991433150857216
这实际上是最接近的可表示 double值(value)。如果可以的话 print the exact valuedouble从第一个示例开始,这就是它要打印的内容。当您添加额外的额外数字时,您会超过 的最大值。数字文字,因此你收到的另一个异常(exception)。
C# 不一致
与 Powershell 不同,C# 使用 整数文字 默认情况下,这就是为什么你会得到更少数字的异常(exception)。添加 D C# 中的后缀将为您提供更大的范围。以下工作正常,将是 double .
var h = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999D;
再增加一位将引发以下错误:

error CS0594: Floating-point constant is outside the range of type 'double'


请注意,在 Powershell 中 D后缀用于 decimal文字而不是 double . double 没有明确的后缀-- 它被假定为默认值。
解决方案
回到您最初的问题,根据您的 Powershell 版本,解决方案可能会有所不同: [BigInt]::Parse如果您使用的是 Windows Powershell 或 Powershell Core <= v6.2,一种选择是使用 BigInteger.Parse :
[bigint]::Parse("99999999999999999999999999999") 
输出:
99999999999999999999999999999
大值文字
正如评论中所指出的,另一个有效的选择是将文字括在引号中。
[bigint]'99999999999999999999999999999' 
输出
99999999999999999999999999999
不管它看起来如何,这是 不是 [bigint]::new([string]) 的简写(见下文)。这是一种确保文字不被视为 double 的方法。而是作为具有许多数字的整数文字,即所谓的“大值文字”。见 this section的文档。 N积分后缀 (v7.0+)
Powershell Core 6.2 为整数类型引入了许多新的文字后缀,例如无符号、 short , 和 byte但没有为 bigint介绍一个.这是通过 n 在 Powershell Core 7.0 中出现的后缀。这意味着您现在可以执行以下操作:
99999999999999999999999999999n 
输出:
99999999999999999999999999999
the documentation有关 Powershell Core 中可用后缀的更多信息。 [BigInt]::new如果您想尝试 [bigint]::new('literal') Powershell 识别出您打算将该值用作文字。实际上没有 BigInt 的构造函数接受 string (我们为此使用 Parse)也没有接受另一个 BigInt 的构造函数.然而,有一个构造函数接受 double .我们的大值文字将从 BigInt 开始, Powershell 将隐式转换为 double (失去精度)然后将其传递给 [bigint]::new([double])作为最佳匹配,再次给出错误结果:
[bigint]::new('99999999999999999999999999999') 
输出:
99999999999999991433150857216

关于c# - PowerShell 和 C# 中的 BigInt 不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62974138/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com