According to microsoft documentation the [BigInt] datatype seems to have no defined maximum value and theoretically can hold an infinitely large number, but I found that after the 28th digit, some weird things start to occur:
PS C:\Users\Neko> [BigInt]9999999999999999999999999999
9999999999999999999999999999
PS C:\Users\Neko> [BigInt]99999999999999999999999999999
99999999999999991433150857216
As you can see, on the first command1, the BigInt works as intended, but with one more digit, some falloff seems to occur where it translates 99999999999999999999999999999 to 99999999999999991433150857216 however, the prompt throws no error and you can continue to add more digits until the 310th digit
PS C:\Users\Neko> [BigInt]99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336
PS C:\Users\Neko\> [BigInt]999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
which will throw the error
At line:1 char:318
+ ... 999999999999999999999999999999999999999999999999999999999999999999999
+ ~
The numeric constant 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 is not valid.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : BadNumericConstant
Which I believe is a console issue rather than a BigInt issue because the error doesn't mention the [BigInt] datatype unlike numbers too big for other datatypes like
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
As for C#, System.Numerics.BigInt will start throwing an error at the 20th digit, 99999999999999999999 when hard coded:
namespace Test
{
class Test
{
static void Main()
{
System.Numerics.BigInteger TestInput;
System.Numerics.BigInteger Test = 99999999999999999999;
System.Console.WriteLine(Test);
}
}
}
When trying to build in Visual Studio I get the error
Integral constant is too large
However, I can enter a bigger number to ReadLine without causing an error
namespace Test
{
class Test
{
static void Main()
{
System.Numerics.BigInteger TestInput;
TestInput = System.Numerics.BigInteger.Parse(System.Console.ReadLine());
System.Console.WriteLine(TestInput);
}
}
}
Which seems to indeed be infinite. The input
99999999999...
(24720 characters total) works fine2
So what is causing all of this weird activity with [BigInt]?
1 which is 28 digits according to ([Char[]]"$([BigInt]9999999999999999999999999999)").count
2 I am too lazy to count the digits and trying to parse the digits into PowerShell causes an error. According to this it is 24720 characters
TLDR: Use [BigInt]::Parse or 'literal' syntax prior to Powershell Core 7.0; otherwise use the n suffix.
The Problem - double literals
When it comes to un-suffixed literals, Powershell will use the first type the value fits in. The order for integral literals is int, long, decimal and then double. From the documentation for Powershell 5.1 (bolding mine; this paragraph is the same for 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].
In your case the value exceeds that of decimal.MaxValue so your literal is by default a double literal. That double value is not exactly representable and is "converted" to the closest representable double.
$h = [double]99999999999999999999999999999
"{0:G29}" -f $h
Outputs
99999999999999991000000000000
Obviously that's not the exact number, just a representation in string form. But it gives you an idea what's going on. Now we take this inexact double value and we cast it to BigInt. The original loss in precision is transferred over and compounded upon by the conversion operator. This is what is actually happening in Powershell (note the cast to BigInt):
$h = [BigInt][double]99999999999999999999999999999
"{0:G}" -f $h
Outputs
99999999999999991433150857216
This is in fact the closest representable double value. If you could print the exact value of the double from the first example, this is what it would print. When you add the additional extra digits, you exceed the largest value of a numeric literal, thus the other exception you received.
C# Inconsistencies
Unlike Powershell, C# uses integral literals by default which is why you get the exception for a lot fewer digits. Adding the D suffix in C# will give you a larger range. The following works fine and will be a double.
var h = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999D;
Adding one more digit will raise the following error:
error CS0594: Floating-point constant is outside the range of type 'double'
Note that in Powershell the D suffix is used for decimal literals and not double. There is not an explicit suffix for double--it is assumed to be the default.
Solutions
Back to your original problem, depending on your Powershell version the solution may vary:
[BigInt]::Parse
If you are using Windows Powershell or Powershell Core <= v6.2, one option is to use BigInteger.Parse:
[bigint]::Parse("99999999999999999999999999999")
Outputs:
99999999999999999999999999999
Large Value Literals
As pointed out in the comments, another option that works is to enclose the literal in quotes.
[bigint]'99999999999999999999999999999'
Outputs
99999999999999999999999999999
Despite how it looks, this is not shorthand for [bigint]::new([string]) (see below). This is instead a way to ensure that the literal is not treated as a double but rather as an integral literal with many digits, a so-called "large value literal". See this section of the docs.
N Integral Suffix (v7.0+)
Powershell Core 6.2 introduced many new literal suffixes for integral types such as unsigned, short, and byte but did not introduce one for bigint. That came along in Powershell Core 7.0 via the n suffix. This means you can now do the following:
99999999999999999999999999999n
Outputs:
99999999999999999999999999999
See the documentation for more information on the suffixes available in Powershell Core.
[BigInt]::new
If you were to try [bigint]::new('literal') Powershell recognizes that you intend to use the value as a literal. There is in fact no constructor for BigInt that accepts a string (we use Parse for that) nor is there a constructor which accepts another BigInt. There is however a constructor that takes a double. Our large-value literal will start as a BigInt, Powershell will then implicitly convert that to a double (losing precision) and then pass it to [bigint]::new([double]) as the best match, once again giving an incorrect result:
[bigint]::new('99999999999999999999999999999')
Outputs:
99999999999999991433150857216
Unfortunately C# have not literal for BigInteger. There are two ways to instantiate BigInteger:
Convert from primitive type like int, long (cast or using constructor)
Parse from string using BigInteger.Parse
BigInteger test = BigInteger.Parse("32439845934875938475398457938457389475983475893475389457839475");
Console.WriteLine(test.ToString());
// output: 32439845934875938475398457938457389475983475893475389457839475
See How PowerShell parses numeric literals
To complement the existing, helpful answers - notably pinkfloydx33's - with a succinct summary:
By default, all PowerShell versions up to at least v7.0 use [double] as the data type for number literals that are larger than [decimal]::MaxValue, which invariably leads to a loss of accuracy.
Up to v6.x (which includes Windows PowerShell), the only way to avoid this is to use [bigint]::Parse() with the number represented as a string:
[bigint]::Parse('99999999999999999999999999999')
# A *cast* works too, as also shown in pinkfloydx33's answer:
[bigint] '99999999999999999999999999999'
In v7+, you can use the n suffix to designate a number literal as a [bigint]:
99999999999999999999999999999n # v7+; parses as a [bigint], due to suffix 'n'
Note: Arguably, given that PowerShell usually automatically picks an appropriate number type, it should assume n in this case, i.e. it should parse unsuffixed 99999999999999999999999999999 as a [bigint], not as a [double] - see this GitHub proposal.
Further reading:
See about_Numeric_Literals, which shows all number-type suffixes, including what PowerShell version they were introduced in.
This answer summarizes how number literals are interpreted in PowerShell.
In short: For integer literals, [int] is the smallest type ever chosen, with [long] or [decimal] chosen as needed to accommodate larger values, with [double] used for values beyond [decimal]::MaxValue.
A little more information coming at this from a metadata perspective,
PowerShell and C# will both use the same module in .NET Core to get the BigInt datatype, and you can view the metadata for the BigInteger struct in
C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Runtime.Numerics.dll
This includes the constructors for
public BigInteger(byte[] value);
public BigInteger(decimal value);
public BigInteger(double value);
public BigInteger(int value);
public BigInteger(long value);
public BigInteger(float value);
public BigInteger(uint value);
public BigInteger(ulong value);
public BigInteger(ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);
Which means the base
System.Numerics.BigInteger test = 12345;
Will inadvertently attempt to convert the value passed to the constructor into one of these datatypes which the highest value it could take, the maximum value of double, however C# will not try to convert a number to double unless specified with the D suffix so the max value that doesn't need a suffix would be ULong which has the max value of 18446744073709551615 (According to ULong.MaxValue) which happens to be less than 99999999999999999999, the number that caused the integral constant error, but greater than 9999999999999999999, one character less. This is why simply doing
System.Numerics.BigInteger test = 99999999999999999999;
will have an error. However, the Parse() method in BigInteger can take values other than the integer types from the constructor, it take strings:
public static BigInteger Parse(ReadOnlySpan<char> value, NumberStyles style = NumberStyles.Integer, IFormatProvider provider = null);
public static BigInteger Parse(string value);
public static BigInteger Parse(string value, NumberStyles style);
public static BigInteger Parse(string value, NumberStyles style, IFormatProvider provider);
public static BigInteger Parse(string value, IFormatProvider provider);
As you can see, the Parse() method for System.Numerics.BigInteger will take string arguments which have no limits since they aren't integers but words. This is why the Parse() method indeed will give you unlimited value space.
As for PowerShell, like in other answers say, anything past the [decimal] max value will attempt to get converted to the [double] datatype which has many inaccuracies and the [double] datatype's max value is 309 digits and that is why errors only show up after the 309th digit.
[double]::MaxValue
1.79769313486232E+308
To convert this to normal value not in scientific notation, we will move the decimal point over 308 times resulting in about
179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
being the highest possible double. The `[double] datatype in PowerShell also has very strange properties that are also very inaccurate like
[BigInt][double]9999999999999999999999
10000000000000000000000
[BigInt][double]9999999999999999999999999
10000000000000000905969664
[double]9999999999999999999
1E+19
Since PowerShell gets the BigInt type also from the same struct as C#, the methods and constructors are the same and Parse() will also work the same way in PowerShell as it does in C#. There were changes in PowerShell 7 allowing the N suffix to automatically be converted directly to BigInt.
BigInt also doesn't use scientific notation so it always will get the exact value if another datatype in used so to to get the exact value you could use
[BigInt]([double]::MaxValue)
Which will get you
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
being the highest possible double.
Commands that you want
PowerShell 6.x and below
[BigInt]::Parse("99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999")
PowerShell 7.0 and above
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999N
C#
System.Numerics.Biginteger test = System.Numerics.BigInteger.Parse("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999")
Related
so I just started experimenting with C#. I have one line of code and the output is a "?".
Code: Console.WriteLine(Math.Pow(Math.Exp(1200), 0.005d));
Output: ?
I am using Visual Studio and it also says exited with code 0.
It should output 403.4287934927351. I also tried it out with Geogebra and it's correct as shown in the image so it's not infinity.
C# double type (which is returned by Math.Exp function) is a fixed-size type (64 bits), and so it cannot represent arbitrary large numbers. Largest number it can represent is double.MaxValue constant, and it's of order 10^308, which is less than what you are trying to compute (e^2000).
When result of computation exceeds maximum representable value - special "number" representing Infinity is returned. So
double x = Math.Exp(1200); // cannot represent this with double type
bool isInifinite = double.IsInfinity(x); // true
After you got this "infinity" - all other computations involving it will just return infinity back, there is nothing else they can do. So then whole expression Math.Pow(Math.Exp(1200), 0.005d)) returns "infinity".
When you try to write result to console, it gets converted to string. The rules for converting mentioned infinity to string are as follows:
Regardless of the format string, if the value of a Single or Double
floating-point type is positive infinity, negative infinity, or not a
number (NaN), the formatted string is the value of the respective
PositiveInfinitySymbol, NegativeInfinitySymbol, or NaNSymbol property
that is specified by the currently applicable NumberFormatInfo object.
In your current culture, PositiveInfinitySymbol is likely "∞", but your console encoding likely cannot represent this symbol, so it outputs "?". You can change console encoding to UTF8 like this:
Console.OutputEncoding = Encoding.UTF8;
And then it will show "∞" correctly.
There is no framework-provided type to work with arbitrary sized rational numbers, as far as I know. For integer there is BigInteger type though.
In this specific case you can do fine with just double, because you can do the same thing with:
Console.WriteLine(Math.Exp(1200 * 0.005d));
// outputs 403.4287934927351
Now there are no intermediate results exceeding capacity of double, and so it works fine.
For cases where it's not possible - there are third party libraries which allow to work with arbitrary large rationals.
we are upgrading our code from C++ to C# and in alot of place we are formating strings.
for exmaple we have something like that:
OurString.Format("amount = %0.2Lf", (long double)amount);
How to convert the %0.2Lf into C# format ?
i've tried the following code but it's not the same
string formatString = String.Format("amount = {0}", (long double)amount));
thx
Use format strings: http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
You probably want either N2 or F2, depending on whether to include the thousands separator. So,
string formatString = String.Format("amount = {0:F2}", amount);
Edit:
As an simple FYI, if you're constructing a string in a series of distinct steps, you might want to use the StringBuilder class, which has an AppendFormat() method that accepts the same formating options as string.Format():
var builder = new StringBuilder();
// ... Your code to build the first part of the string
builder.AppendFormat("amount = {0:F2}", amount);
// ... whatever else you need to add
builder.ToString(); // outputs your final/completed string.
Whether you use StringBuilder or not depends on how critical memory management and/or performance is to the application; strings in C# are immutable, so when you concat them you are actually creating a brand new string. You can read more here: http://msdn.microsoft.com/en-us/library/system.string.aspx#Immutability
As Tieson wrote, F2... Just remember that in C the default locale is the C locale. So for example 0.00, while in C# the default locale is the current locale of the user (here in Italy 0,00). So it would be better to do:
string formatString = String.Format(CultureInfo.InvariantLocale,
"amount = {0:F2}", amount);
if you want to always everywhere format your digits in the same manner. Remember that when I told "here in Italy" also means "if I take my Italian Windows 8 in the USA the default locale will be Italian for me."
Ah... and there aren't long doubles in C# (or in .NET, or in newer versions of VC++ for that reason). Only doubles.
I'll add that using a double (or a long double) for money is an antipattern in itself... There is the decimal type for it.
The Decimal value type represents decimal numbers ranging from positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335. The Decimal value type is appropriate for financial calculations that require large numbers of significant integral and fractional digits and no round-off errors. The Decimal type does not eliminate the need for rounding. Rather, it minimizes errors due to rounding. For example, the following code produces a result of 0.9999999999999999999999999999 instead of 1.
From the msdn page :
public static double ToDouble(
char value
)
Parameters
value
Type: System.Char
The Unicode character to convert.
Return Value
Type: System.Double
This conversion is not supported. No value is returned.
If it is not supported, why is it implemented in the first place ?
It is not the only one. Convert.ToBoolean(char), ToDateTime, ToDecimal and ToSingle are also not supported, they all throw InvalidCastException like ToDouble does.
This is just .NET design trying to keep you out of trouble. Converting a char to an integral type is reasonable, you can look at the Unicode mapping tables and count the codepoints. But what would a conversion to Boolean mean? What Unicode code point is True? ToDateTime requires no explanation. How could a character ever be a fractional value? There are no half or quarter codepoints.
You can make it work, convert to Int32 first and then convert to Double. But by all means, check your code and make sure that it is a senseful thing to do. The .NET designers thought it wasn't. They were right.
As per MSDN, this function is keep reserved for future use in .Net 2.0 and it's kept till 4.5 for supporting previous version of .net frameworks.
They will implement this if future OS will support this type of conversion. Currently, OS stores the char as int, so not providing the way to cast char to double due to lots of inner conversions.
Due to internal storage format, same limitation is with Convert.ToDouble(DateTime).
Each character has a corresponding integer. For example:
Convert.ToInt16('a') -> returns 97.
I guess the main reason why the Convert doesn't support to convert from a char the other types is that the second nature of a character is the integer type.
Maybe a more clear example is the following code:
char a = 'a';
int aVal = (int)a;
Which actually Convert.ToInt32 does ( but also raises the overflow exception)
A char can be implicitly converted to ushort, int, uint, long, ulong, float, double, or decimal.
The following two statements will cause a compiler overflow error ( reason being that constant expressions are by default checked for overflow):
int i=(int)(int.MaxValue+100); // error
long l=(long)(int.MaxValue+100); // error
But if compiler is able to figure out that adding the two values causes an overflow, why doesn't it then promote both int.MaxValue and 100 to long and only then try to add them together? As far as I can tell, that shouldn't be a problem since according to the following quote, the integer literal can also be of type long:
When an integer literal has no suffix,
its type is the first of these types
in which its value can be represented:
int, uint, long, ulong.
thanx
The literal 100 can be represented as an int, which is the first of those four types in that order, so it's made an int.
int.MaxValue is not a literal. It is a public constant field of type int.
So, the addition operation is int + int, which results in an int, which then overflows for this case.
To turn the literal 100 into a long so you perform long integer addition, suffix it with L:
long l = int.MaxValue + 100L;
The rules are:
int + int is int, not long
the default for arithmetic on constants is "checked"; the default for arithmetic on non-constants is "unchecked"
100 and int.MaxValue are constants
Therefore the correct behaviour according to the specification is to do overflow checking at compile time and give an error.
If instead you said:
int x = 100;
int y = int.MaxValue;
long z = x + y;
then the right behaviour is to do an unchecked addition of two integers, wrap around on overflow, and then convert the resulting integer to long.
If what you want is long arithmetic then you have to say so. Convert one of the operands to long.
The reason is all in the sequence. If you read your code, it does: Take an int variable with value MAX, and add 100 to it. This is true in both cases, and this is the code that will be executed before anything else will happen.
If you want to make it work. do
long l = ((long)int.MaxValue)+100;
The short answer, I would imagine, is because it hasn't been designed to. Whenever MS adds features to the C# compiler (or when anyone adds features to anything), there has to be a cost-benefit analysis. People have to want the feature, and the cost of implementing the feature (in terms of time coding and testing and the opportunity cost of some other feature that could be implemented) must be outweighed by the potential benefit that the feature provides to the developer.
In your case, the way to get the compiler to do what you want is simple, obvious, and clear. If they add:
Infer the type of a numeric expression consisting only of constants and literals to be the minimal type that can contain the resulting value
That means that they now have more code paths to check and more unit tests to write. Changing expected behavior also means that there is probably someone who relies on this documented fact whose code will now be invalid because the inferences could be different.
It's not the compiler's place to promote types based on the result of run-time expressions.
Both int.MaxValue and 100 are integers. I would find the potential for problems if the compiler change the type based on the result of an expression.
Well, what do you expect? You are saying int.MaxValue+100 which goes over the maximum value allowed for an integer! To make it work for the long, do this:
((long)(int.MaxValue)) + 100;
Don't assume the compiler will promote the value to long automatically. That would be even stranger.
Why does (string)int32 always throw: Cannot convert type 'int' to 'string'
public class Foo
{
private int FooID;
public Foo()
{
FooID = 4;
string s = (string)FooID; //throws compile error
string sss = FooID.ToString(); //no compile error
}
}
Because there is no type conversion defined from Int32 to string. That's what the ToString method is for.
If you did this:
string s = (string)70;
What would you expect to be in s?
A. "70" the number written the way humans would read it.
B. "+70" the number written with a positive indicator in front.
C. "F" the character represented by ASCII code 70.
D. "\x00\x00\x00F" the four bytes of an int each separately converted to their ASCII representation.
E. "\x0000F" the int split into two sets of two bytes each representing a Unicode character.
F. "1000110" the binary representation for 70.
G. "$70" the integer converted to a currency
H. Something else.
The compiler can't tell so it makes you do it the long way.
There are two "long ways". The first is to use one of the the Convert.ToString() overloads something like this:
string s = Convert.ToString(-70, 10);
This means that it will convert the number to a string using base 10 notation. If the number is negative it displays a "-" at the start, otherwise it just shows the number. However if you convert to Binary, Octal or Hexadecimal, negative numbers are displayed in twos complement so Convert.ToString(-7, 16) becomes "ffffffba".
The other "long way" is to use ToString with a string formatter like this:
string s2 = 70.ToString("D");
The D is a formatter code and tells the ToString method how to convert to a string. Some of the interesting codes are listed below:
"D" Decimal format which is digits 0-9 with a "-" at the start if required. E.g. -70 becomes "-70".
"D8" I've shown 8 but could be any number. The same as decimal, but it pads with zeros to the required length. E.g. -70 becomes "-00000070".
"N" Thousand separators are inserted and ".00" is added at the end. E.g. -1000 becomes "-1,000.00".
"C" A currency symbol is added at the start after the "-" then it is the same as "N". E.g. Using en-Gb culture -1000 becomes "-£1,000.00".
"X" Hexadecimal format. E.g. -70 becomes "46".
Note: These formats are dependent upon the current culture settings so if you are using en-Us you will get a "$" instead of a "£" when using format code "C".
For more information on format codes see MSDN - Standard Numeric Format Strings.
When performing a cast operation like (string)30, you're basically telling the computer that "this object is similar enough to the object I'm casting to that I won't lose much (or any) data/functionality".
When casting a number to a string, there is a "loss" in data. A string can not perform mathematical operations, and it can't do number related things.
That is why you can do this:
int test1 = 34;
double test2 = (double)test1;
But not this:
int test1 = 34;
string test2 = (string)test1;
This example isn't perfect since (IIRC) the conversion here is implicit, however the idea is that when converting to a double, you don't lose any information. That data type can still basically act the same whether it's a double or an int. The same can't be said of an int to a string.
Casting is (usually) only allowed when you won't lose much functionality after the conversion is done.
The .ToString() method is different from casting because it's just a method that returns a string data type.
Just another note: In general, if you want to do an explicit conversion like this (and I agree with many other answers here as to why it needs to be an explicit conversion) don't overlook the Convert type. It is designed for these sorts of primitive/simple type conversions.
I know that when starting in C# (and coming from C++) I found myself running into type casts that seemed like they should have worked. C++ is just a bit more liberal when it comes to this sort of thing, so in C# the designers wanted you to know when your type conversion were ambiguous or ill-advised. The Convert type then fills in the gaps by allowing you to explicitly convert and understand the side-effects.
Int doesn't have an explicit operator to string. However, they have Int32.ToString();. Maybe you can create one with Extension methods, if you really want to.
Because C# does not know how to convert int to string, the library (.ToString) does.
Int32 can't be casted to string because C# compiler doesn't know how to converter from one type to another.
Why is that, you will ask the reason is simple int32 is type integer/numerical and string is, oh well type string/characters. You may be able to convert from numerical type to another numerical type (ex. float to int, but be warned possible loss of accuracy).
If all possible casts where coded in the compiler the compiler would become too slow and certainly would miss much of the possible casts created for user defined types which is a major NO NO.
So the workaround is that any object in C# has a function inherited .ToString() that knows how to handle every type because .ToString() is specifically coded for the specific type, and as you guessed by now returns a string.
After all Int32 type is some bits in memory (32 bits to be exact) and string type is another pile of bits (how many bits depends on how much has been allocated) the compiler/runtime doesn't know anything just by itself looking at that data until now. .ToString() function accesses the specific metadata needed to convert from one to the other.
I just found the answer. ToString works fine on an int variable. You just have to make sure you add the brackets.
ie...
int intMyInt=32;
string strMyString = intMyInt.ToString();
VB .net is perfectly capable of casting from an int to string... in fact so is Java. Why should C# have a problem with it? Sometimes it is necessary to use a number value in calculations and then display the result in a string format. How else would you manage to display the result of a calculation in a TextBox?
The responses given here make no sense. There must be a way to cast an int as a string.