Int.TryParse() returns false always - c#

I have following code
int varOut;
int.TryParse(txt1.Text, out varOut); // Here txt1.Text = 4286656181793660
Here txt1.Text is the random 16 digit number generated by JavaScript which is an integer. But the above code always return false i.e. varOut value is always zero.
What I am doing wrong here ?

The limit for int (32-bit integer) is -2,147,483,648 to 2,147,483,647. Your number is too large.
For large integer number such as your case, try to Parse using long.TryParse (or Int64.TryParse since Int64 is long in C#) instead. The limit for long number is of the range of -9.2e18 to 9.2e18*
long varOut;
long.TryParse(txt1.Text, out varOut); // Here txt1.Text = 4286656181793660
It should be sufficient for your number, which is only around 4.2e15 (4,286,656,181,793,660).
Alternatively, you may want to consider using decimal.TryParse if you want to have decimal number (containing fraction, higher precision).
decimal varOut;
decimal.TryParse(txt1.Text, out varOut); // Here txt1.Text = 4286656181793660
It is 128-bit data type, with the range of -7.9e28 to 7.9e28, and 28-29 significant digits precision, fits best for any calculation involving money.
And, as a last remark to complete the answer, it may be unsafe to use double - do not use it. Although double has a very high range of ±5.0 × 10e−324 to ±1.7 × 10e308, its precision is only about 15-16 digits (reference).
double varOut;
double.TryParse(txt1.Text, out varOut); // Not a good idea... since the input number is 16-digit Here txt1.Text = 4286656181793660
In this case, your number consists of 16 digits, which is in the borderline of the double precision. Thus, in some cases, you may end up with wrong result. Only if you are sure that your number will be at most 15-digit precision that you are safe to use it.
*-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

int is just shorthand for int32; it's a 32 bit (signed) integer, meaning that it can't hold a number larger than around 2 billion. Your number is larger than that, and so is not a valid int value.

Use MaxLength property to limit the number of digits and user cannot enter more than int32.
TextBox.MaxLength=9

Looks like you may be using value(s) which exceed the capacity of the type you're using... look at https://msdn.microsoft.com/en-us/library/system.int32.maxvalue%28v=vs.110%29.aspx
Store it as a long instead of an int.
https://msdn.microsoft.com/en-us/library/ctetwysk.aspx

You should use long instead of int. Your number is too large for int

Use long.TryParse()
Your number is too large to convert into int.
or you can use int64.tryparse

Related

How can doubles represent higher numbers than decimals if they can't hold as many significant figures?

I may very well have not the proper understanding of significant figures, but the book
C# 6.0 in a Nutshell by Joseph Albahari and Ben Albahari (O’Reilly).
Copyright 2016 Joseph Albahari and Ben Albahari, 978-1-491-92706-9.
provides the table below for comparing double and decimal:
Is it not counter-intuitive that, on the one hand, a double can hold a smaller quantity of significant figures, while on the other it can represent numbers way bigger than decimal, which can hold a higher quantity of significant figures ?
Imagine you were told you can store a value, but were given a limitation: You can only store 10 digits, 0-9 and a negative symbol. You can create the rules to decode the value, so you can store any value.
The first way you store things is simply as the value xxxxxxxxxx, meaning the number 123 is stored as 0000000123. Simple to store and read. This is how an int works.
Now you decide you want to store fractional numbers, so you change the rules a bit. Now you store xxxxxxyyyy, where x is the integer portion and y is the fractional portion. So, 123.98 would be stored as 0001239800. This is roughly how a Decimal value works. You can see the largest value I can store is 9999999999, which translates to 999999.9999. This means I have a hard upper limit on the size of the value, but the number of the significant digits is large at 10.
There is a way to store larger values, and that's to store the x and y components for the formula in xxxxxxyyyy. So, to store 123.98, you need to store 01239800-2, which I can calculate as . This means I can store much bigger numbers by changing 'y', but the number of significant digits is basically fixed at 6. This is basically how a double works.
The answer lies in the way that doubles are encoded. Rather than just being a direct binary representation of a number, they have 3 parts: sign, exponent, and fraction.
The sign is obvious, it controls + or -.
The fraction part is also obvious. It's binary fraction that represents a number in between 0 and 1.
The exponent is where the magic happens. It signifies a scaling factor.
The final float calculation comes out to (-1)^$sign * (1 + $fraction) * 2 ^$exponent
This allows much higher values than a straight decimal number because of the exponent. There's a lot of reading out there on why this works and how to do addition and multiplication with these encoded numbers. Google around for "IEEE floating point format" or whatever topic you need. Hope that helps!
The Range has nothing to do with the precision. Double has a binary representation (base 2). Not all numbers can be represented exactly as we humans know them in the decimal format. Not to mention and accumulated rounding errors of addition and division. A larger range means a greater MAX VALUE and a smaller MIN VALUE than decimal.
Decimal on the other side is (base 10). It has a smaller range (smaller MAX VALUE and larger MIN VALUE). This has nothing to do with precision, since it is not represented using floating binary point representation, it can represent numbers more precisely and though is recommended for human-made numbers and calculations.

how to get the BigInteger to the pow Double in C#?

I tried to use BigInteger.Pow method to calculate something like 10^12345.987654321 but this method only accept integer number as exponent like this:
BigInteger.Pow(BigInteger x, int y)
so how can I use double number as exponent in above method?
There's no arbitrary precision large number support in C#, so this cannot be done directly. There are some alternatives (such as looking for a 3rd party library), or you can try something like the code below - if the base is small enough, like in your case.
public class StackOverflow_11179289
{
public static void Test()
{
int #base = 10;
double exp = 12345.123;
int intExp = (int)Math.Floor(exp);
double fracExp = exp - intExp;
BigInteger temp = BigInteger.Pow(#base, intExp);
double temp2 = Math.Pow(#base, fracExp);
int fractionBitsForDouble = 52;
for (int i = 0; i < fractionBitsForDouble; i++)
{
temp = BigInteger.Divide(temp, 2);
temp2 *= 2;
}
BigInteger result = BigInteger.Multiply(temp, (BigInteger)temp2);
Console.WriteLine(result);
}
}
The idea is to use big integer math to compute the power of the integer part of the exponent, then use double (64-bit floating point) math to compute the power of the fraction part. Then, using the fact that
a ^ (int + frac) = a ^ int * a ^ frac
we can combine the two values into a single big integer. But simply converting the double value to a BigInteger would lose a lot of its precision, so we first "shift" the precision onto the bigInteger (using the loop above, and the fact that the double type uses 52 bits for the precision), then multiplying the result.
Notice that the result is an approximation, if you want a more precise number, you'll need a library that does arbitrary precision floating point math.
Update: If the base / exponent are small enough that the power would be in the range of double, we can simply do what Sebastian Piu suggested (new BigInteger(Math.Pow((double)#base, exp)))
I like carlosfigueira's answer, but of course the result of his method can only be correct on the first (most significant) 15-17 digits, because a System.Double is used as a multiplier eventually.
It is interesting to note that there does exist a method BigInteger.Log that performs the "inverse" operation. So if you want to calculate Pow(7, 123456.78) you could, in theory, search all BigInteger numbers x to find one number such that BigInteger.Log(x, 7) is equal to 123456.78 or closer to 123456.78 than any other x of type BigInteger.
Of course the logarithm function is increasing, so your search can use some kind of "binary search" (bisection search). Our answer lies between Pow(7, 123456) and Pow(7, 123457) which can both be calculated exactly.
Skip the rest if you want
Now, how can we predict in advance if there are more than one integer whose logarithm is 123456.78, up to the precision of System.Double, or if there is in fact no integer whose logarithm hits that specific Double (the precise result of an ideal Pow function being an irrational number)? In our example, there will be very many integers giving the same Double 123456.78 because the factor m = Pow(7, epsilon) (where epsilon is the smallest positive number such that 123456.78 + epilon has a representation as a Double different from the representation of 123456.78 itself) is big enough that there will be very many integers between the true answer and the true answer multiplied by m.
Remember from calculus that the derivative of the mathemtical function x → Pow(7, x) is x → Log(7)*Pow(7, x), so the slope of the graph of the exponential function in question will be Log(7)*Pow(7, 123456.78). This number multiplied by the above epsilon is still much much greater than one, so there are many integers satisfying our need.
Actually, I think carlosfigueira's method will give a "correct" answer x in the sense that Log(x, 7) has the same representation as a Double as 123456.78 has. But has anyone tried it? :-)
I'll provide another answer that is hopefully more clear. The point is: Since the precision of System.Double is limited to approx. 15-17 decimal digits, the result of any Pow(BigInteger, Double) calculation will have an even more limited precision. Therefore, there's no hope of doing better than carlosfigueira's answer does.
Let me illustrate this with an example. Suppose we wanted to calculate
Pow(10, exponent)
where in this example I choose for exponent the double-precision number
const double exponent = 100.0 * Math.PI;
This is of course only an example. The value of exponent, in decimal, can be given as one of
314.159265358979
314.15926535897933
314.1592653589793258106510620564222335815429687500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
The first of these numbers is what you normally see (15 digits). The second version is produced with exponent.ToString("R") and contains 17 digits. Note that the precision of Double is less than 17 digits. The third representation above is the theoretical "exact" value of exponent. Note that this differs, of course, from the mathematical number 100π near the 17th digit.
To figure out what Pow(10, exponent) ought to be, I simply did BigInteger.Log10(x) on a lot of numbers x to see how I could reproduce exponent. So the results presented here simply reflect the .NET Framework's implementation of BigInteger.Log10.
It turns out that any BigInteger x from
0x0C3F859904635FC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F85990481FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
makes Log10(x) equal to exponent to the precision of 15 digits. Similarly, any number from
0x0C3F8599047BDEC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
through
0x0C3F8599047D667FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
satisfies Log10(x) == exponent to the precision of Double. Put in another way, any number from the latter range is equally "correct" as the result of Pow(10, exponent), simply because the precision of exponent is so limited.
(Interlude: The bunches of 0s and Fs reveal that .NET's implementation only considers the most significant bytes of x. They don't care to do better, precisely because the Double type has this limited precision.)
Now, the only reason to introduce third-party software, would be if you insist that exponent is to be interpreted as the third of the decimal numbers given above. (It's really a miracle that the Double type allowed you to specify exactly the number you wanted, huh?) In that case, the result of Pow(10, exponent) would be an irrational (but algebraic) number with a tail of never-repeating decimals. It couldn't fit in an integer without rounding/truncating. PS! If we take the exponent to be the real number 100π, the result, mathematically, would be different: some transcendental number, I suspect.

decimal to long - always missing a dot separator

I want to be able to convert a
varchar > decimal > long
when dbreader[11] holds a 3319419,13 as varchar
For example:
decimal d = Convert.ToDecimal(dbreader[11], CultureInfo.InvariantCulture);
I get
d = 3319419.13M
When i convert this to long object I end up with
long i = 3319419
I want to end up with 3319419,1
It never will, I'm afraid. long is a synonym for System.Int64 - a 64 bit integer value so it is unable to store the precision you are asking it to. See here
You cannot end up with 3319419,1 in a long, because long is integer.
Try using a double instead.
EDIT: Now, double happens to be a floating-point number. This means that the number of decimal digits that this type is capable of representing is not fixed, but variable. So, if you want to see a specific number of decimal digits, then this is entirely a matter of display. So, in order to see your double variable with only one digit, convert it to string as follows: String.Format( "{0:00.0}", my_double_variable );
A long is an 8 byte integer (whole number). If you require more precision, use a double (8 byte decimal)
Reality check.
3319419,1
A long is incapable of keeping partial numbers. 1, 2, 3 - not 1, 1.1, 1.2. This is teh definition of a long.
SO, you CAN NOT keep fractional values in a long, regardless what you want. Want to keep fractional values - use a data type that can.
A long does not have any decimals. It is an integer type.
You might want to use double, or keep it as a decimal.

Why can't I pass a large value as an Int32?

I have a number: 94,800,620,800
Float is 4-byte data-type.
Int32 is also 4-byte data-type.
float f = 94800620800; // ok
Int32 t = 94800620800; // error
Please explain this problem. Why I get a error when using Int32. Why I can use this number for float data-type because both of them are 4-byte data-type. Thanks.
Because the number you are trying to assign is larger than the largest possible value for a number of type Int32, which happens to be 2,147,483,647. To note, the maximum value for a Single is 3.402823 × 1038.
The max value for Int32 is 2,147,483,647 - which is less than 94,800,620,800.
A float can take a value in the following range: ±1.5 × 10−45 to ±3.4 × 1038
Also, check out this SO question - what the difference between the float and integer data type when the size is same in java?. It's a Java question, but the concept is the same and there's a detailed explanation of the difference, even though they're the same size.
Because that number is too big for a 4 byte int. Scalar values like Int32 have a minimum and maximum limit (which are -231 and 231 - 1 in this case, respectively), and you simply can't store a value outside this range.
Floating point numbers are stored totally differently, so you won't get compiler errors with huge values, only possible precision problems later, during runtime.
Because of those types internal representation.
float uses something like i,d ^ n where i is the integral part, d is the decimal part and n is the exponent (of course, this happens in base 2).
In this way, you can store bigger numbers in a float, but it won't be accurate as a, say, Int32 in storing integral numbers. If you try to convert
float f = 94800620800;
to an integral type large enough to store its value, it may not be the same as the initial 94800620800.
Integers types are exact representations, while floating point numbers are a combination of significant digits and exponent.
The floating point wiki page is explaining how this works.
Maybe you should read the error message? ;)
Error Integral constant is too large
the maximum valiue of a 32 bit int is 2,147,483,647
the float on the other hand works because it stores a mantissa and exponent, rather than just a single number, so it can cope with a much bigger range at the expense of possibly losing precision
try printing out your float and you will get 94800620000 instead of 94800620800 as the lower bits are lost
Int32 has a max value of 2,147,483,647. Your value is much higher.
Take a look at system.int32.maxvalue
Provided value of the constant expression is not within the range of int datatype.
The range of Int32 goes from − 2,147,483,648 to 2,147,483,647. Your variable is way out of range.

C# - Incrementing a double value (1.212E+25)

I have a double value that equals 1.212E+25
When I throw it out to text I do myVar.ToString("0000000000000000000000")
The problem is even if I do myVar++ 3 or 4 times the value seems to stay the same.
Why is that?
That is because the precision of a double is not sufficient. It simply can't hold that many significant digits.
It will not fit into a long, but probably into a Decimal.
But... do you really need this level of precision?
To expand on the other answer the smallest increase you can make to a double is one Unit in the Last Place, or ULP, as double is a floating point type then the size of an ULP changes, at 1E+25 it will be about 1E+10.
as you can see compared to 1E+10 incrementing by 1 really might as well be adding nothing. which is exactly what double will do, so it wouldnt matter if you tried it 10^25 times it still won't increase unless you try to increase by at least 1 ULP
if incrementing by an ULP is useful you can do this by casting the bits to long and back here is a quick extension method to do that
public static double UlpChange(this double val, int ulp)
{
if (!double.IsInfinity(val) && !double.IsNaN(val))
{
//should probably do something if we are at max or min values
//but its not clear what
long bits = BitConverter.DoubleToInt64Bits(val);
return BitConverter.Int64BitsToDouble(bits + ulp);
}
return val;
}
double (Double) holds about 16 digits of precision and long (Int64) about 18 digits.
Neither of these appear to have sufficient precision for your needs.
However decimal (Decimal) holds up to 30 digits of precision. Although this appears to be great enough for your needs I'd recommend caution in case your requirement grows even larger. In that case you may need a third party numeric library.
Related StackOverflow entries are:
How can I represent a very large integer in .NET?
Big integers in C#
You may want to read the Floating-Point Guide to understand how doubles work.
Basically, a double only has about 16 decimal digits of precision. At a magnitude of 10^25, an increase of 1.0 is below the threshold of precision and gets lost. Due to the binary representation, this may not be obvious.
The smallest increment that'll work is 2^30+1 which will actually increment the double by 2^31. You can test this kind of thing easily enough with LINQPad:
double inc = 1.0;
double num = 1.212e25;
while(num+inc == num) inc*=2;
inc.Dump(); //2147483648 == 2^31
(num+inc == num).Dump(); //false due to loop invariant
(num+(inc/2.0) == num).Dump();//true due to loop invariant
(num+(inc/2.0+1.0) == num).Dump();//false - 2^30+1 suffices to change the number
(num+(inc/2.0+1.0) == num + inc).Dump();//true - 2^30+1 and 2^31 are equiv. increments
((num+(inc/2.0+1.0)) - num == inc ).Dump();//true - the effective increment is 2^31
Since a double is essentially a binary number with limited precision, that means that the smallest possible increment will itself always be a power of two (this increment can be determined directly from the bit-pattern of the double, but it's probably clearer to do so with a loop as above since that's portable across float, double and other floating point representations (which don't exist in .NET).

Categories