I found an example for casting. When I try to cast long to int, I get the following output.
long e = 10;
int x = (int) e ;
WriteLine($"e is {e:N0} and x is {x:N0} ");
e = long.MaxValue;
x = (int) e;
WriteLine($"e is {e:N0} and x is {x:N0} ");
e = 5_000_000_000;
x = (int) e;
WriteLine($"e is {e:N0} and x is {x:N0} ");
For case 1, 10 can fit into int, so there is no issue,
For case 2, value -> long max value won't fit in int, so the output is 1
For case 3, value = 5_000_000_000, which also won't fit in int, so it should output 1, but it outputs 705,032,704 Can anyone explain why we are getting this value?
Output of above code is :
e is 10 and x is 10
e is 9,223,372,036,854,775,807 and x is -1
e is 5,000,000,000 and x is 705,032,704
The reason is that under the covers we're working in binary, and when we cast to a smaller binary value we take as many binary bits as we can from the old value to create our new value.
5,000,000,000 in binary is 100101010000001011111001000000000. If we put this in 32 bits (the size of an int) we get 00101010000001011111001000000000. We just lose the leading 1 because the original number is 33 bits. If we convert that to decimal it is 705032704.
This converter is useful to see this.
Edit:
For long.MaxValue becoming -1 we have to understand how we represent negative numbers in binary. We use the leftmost bit. If it's zero the number is positive, if it's one the number is negative. So for a 64-bit number the maximum positive value is 0 plus 63 1's: 0111111111111111111111111111111111111111111111111111111111111111. If we have 64 1's the number is negative, in fact it's -1 by the way negative numbers work, and obviously that isn't the maximum possible value.
Now if we take the rightmost 32 bits of that big binary number we get 32 1's in a row, and that is -1. The BBC has quite a good explanation of negative number representations in binary.
You need to look at (int)e operation like (e % int.MaxValue), so in your example you get the following:
long.MaxValue % int.MaxValue = 1
5000000000 % int.MaxValue = 705032704
Related
How come dividing two 32 bit int numbers as ( int / int ) returns to me 0, but if I use Decimal.Divide() I get the correct answer? I'm by no means a c# guy.
int is an integer type; dividing two ints performs an integer division, i.e. the fractional part is truncated since it can't be stored in the result type (also int!). Decimal, by contrast, has got a fractional part. By invoking Decimal.Divide, your int arguments get implicitly converted to Decimals.
You can enforce non-integer division on int arguments by explicitly casting at least one of the arguments to a floating-point type, e.g.:
int a = 42;
int b = 23;
double result = (double)a / b;
In the first case, you're doing integer division, so the result is truncated (the decimal part is chopped off) and an integer is returned.
In the second case, the ints are converted to decimals first, and the result is a decimal. Hence they are not truncated and you get the correct result.
The following line:
int a = 1, b = 2;
object result = a / b;
...will be performed using integer arithmetic. Decimal.Divide on the other hand takes two parameters of the type Decimal, so the division will be performed on decimal values rather than integer values. That is equivalent of this:
int a = 1, b = 2;
object result = (Decimal)a / (Decimal)b;
To examine this, you can add the following code lines after each of the above examples:
Console.WriteLine(result.ToString());
Console.WriteLine(result.GetType().ToString());
The output in the first case will be
0
System.Int32
..and in the second case:
0,5
System.Decimal
I reckon Decimal.Divide(decimal, decimal) implicitly converts its 2 int arguments to decimals before returning a decimal value (precise) where as 4/5 is treated as integer division and returns 0
You want to cast the numbers:
double c = (double)a/(double)b;
Note: If any of the arguments in C# is a double, a double divide is used which results in a double. So, the following would work too:
double c = (double)a/b;
here is a Small Program :
static void Main(string[] args)
{
int a=0, b = 0, c = 0;
int n = Convert.ToInt16(Console.ReadLine());
string[] arr_temp = Console.ReadLine().Split(' ');
int[] arr = Array.ConvertAll(arr_temp, Int32.Parse);
foreach (int i in arr)
{
if (i > 0) a++;
else if (i < 0) b++;
else c++;
}
Console.WriteLine("{0}", (double)a / n);
Console.WriteLine("{0}", (double)b / n);
Console.WriteLine("{0}", (double)c / n);
Console.ReadKey();
}
In my case nothing worked above.
what I want to do is divide 278 by 575 and multiply by 100 to find percentage.
double p = (double)((PeopleCount * 1.0 / AllPeopleCount * 1.0) * 100.0);
%: 48,3478260869565 --> 278 / 575 ---> 0
%: 51,6521739130435 --> 297 / 575 ---> 0
if I multiply the PeopleCount by 1.0 it makes it decimal and division will be 48.34...
also multiply by 100.0 not 100.
If you are looking for 0 < a < 1 answer, int / int will not suffice. int / int does integer division. Try casting one of the int's to a double inside the operation.
The answer marked as such is very nearly there, but I think it is worth adding that there is a difference between using double and decimal.
I would not do a better job explaining the concepts than Wikipedia, so I will just provide the pointers:
floating-point arithmetic
decimal data type
In financial systems, it is often a requirement that we can guarantee a certain number of (base-10) decimal places accuracy. This is generally impossible if the input/source data is in base-10 but we perform the arithmetic in base-2 (because the number of decimal places required for the decimal expansion of a number depends on the base; one third takes infinitely many decimal places to express in base-10 as 0.333333..., but it takes only one decimal in base-3: 0.1).
Floating-point numbers are faster to work with (in terms of CPU time; programming-wise they are equally simple) and preferred whenever you want to minimize rounding error (as in scientific applications).
I just converted 16 digit number as a float value.
float myVal =(float) 4447962230071312;
Console.WriteLine(myVal);
This gives the output:
4.44796223007131E+15
I tried below code,
long originalVal = (long)myVal;
Console.WriteLine(originalVal);
This gives the output:
4447962352582656
Console.WriteLine(myVal.ToString("0.#########"));
This gives the output:
4447962000000000
since, How to get back original value of 4447962230071312
float (or Single) uses 23 bits for fractional part only, and thus Single can represent integer values without round error up to
2**(23 + 1) - 1 == 16777215
you can switch to double which has 52 bit fractional part and so can represent integer value up to
2**(52 + 1) - 1 == 9007199254740991 > 4447962230071312
For details, see
https://en.wikipedia.org/wiki/Single-precision_floating-point_format
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
Code:
double myVal = 4447962230071312.0;
long originalVal = (long)myVal;
i read C# book, and there is this example. the question is, why the heck float lose the numeric "1" from int value???
isn't float have bigger magnitude?
int i1 = 100000001;
float f = i1; // Magnitude preserved, precision lost (WHY? #_#)
int i2 = (int)f; // 100000000
A float is a 32 bit number made up of a 24 bit mantissa and an 8 bit exponent. What happens when
float f = ii;
is an attempt to squeeze a 32 bit integer into a 24 bit mantissa. The mantissa will only store 24 bits (around 6-7 significant figures) so anything past the 6th or 7th digit will be lost.
If the assignment is made with a double, which has more significant digits, the value will be preserved.
float was not designed for big integer numbers. If you want to use big numbers and you know it is not always integers, use double.
int i1 = 100000001;
double f = Convert.ToDouble(i1);
int i2 = Convert.ToInt32(f); // 100000001
If all integers and you will want to be able to do calculations with them use Int64 instead of int.
I can't find any good examples of how I can convert a fractional decimal From base 10 to base K in C#
I'm thinking something like
double mynumber = 0.142857;
int mybase = 4;
string myNumberAsString = mynumber.ToString();
do
{
myNumberAsString = "0123456789"[mynumber % mybase] + myNumberAsString ;
mynumber /= mybase;
}
while (mynumber > 0);
Console.WriteLine("# in base 4 is: " + myNumberAsString);
In order to convert decimal part of number from base 10 to base K you have to multiply the number by K until there is no more fractions left in number. You have to get the integer part of number each time you do multiply and erase the integer part after getting it.
double mynumber = 0.142857;
int mybase = 4;
string result = ""; // result will be stored here
while (mynumber > 0) // do multiply and get the int part until number is zero
{
mynumber *= mybase; // do multiply by base and store it in number.
result += string.Format("{0}", (int)mynumber); // store the int part.
mynumber -= (int) mynumber; // remove the int part.
}
Console.WriteLine(result);
A simple example
Convert 0.625 from base 10 to base 2.
Multiply 0.625 by 2. 0.625 => 1.25
Store the integer part and erase it from number. store int part in string "" + "1" = "1". erase int part 1.25 => 0.25
0.25 is bigger than 0. repeat
Multiply 0.25 by 2. 0.25 => 0.5
Store the integer part and erase it from number. store int part in string "1" + "0" = "10". erase int part. 0.5 => 0.5
0.5 is bigger than 0. repeat
Multiply 0.5 by 2. 0.5 => 1.0
Store the integer part and erase it from number. store int part in string "10" + "1" = "101". erase int part 1.0 => 0.0
0.0 is not bigger than 0. The string is now fraction part of 0.625 in base 2
Note:
if you want to convert to higher base than 10 its common to use letters. for example numbers in base 16 is 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F. in this algorithm you have to replace numbers bigger than 9 into letters.
So in order to support up to base 16 change the code a little bit.
while (mynumber > 0)
{
mynumber *= mybase;
result += string.Format("{0}", "0123456789ABCDEF"[(int) mynumber]); // supports up to base 16.
mynumber -= (int) mynumber;
}
You can add more letters to support even higher bases.
some times you may get repeating decimals. for example number 0.1 in base 2 will be "0_0011" where the part after _ is repeating. unfortunately there is no easy way to understand it due to accuracy of floating type and errors in computation. so for number 0.1 in base 2 you will get something like this.
00011001100110011001100110011001100
Take a look at here for the solution to this problem.
This obviously doesn't work.
BigInteger Total = 1000000000000000000000000000000000000000000000000000022234235423534543;
BigInteger Actual = 83450348250384508349058934085;
string Percent = ((Decimal)100.0/Total*Actual).ToString()+"%";
The question is, how to I get my precise percent?
Currently I use..
string sTotal = (task.End - task.Start).ToString();
BigInteger current = task.End;
string sCurrent = (task.End-current).ToString().PadLeft(sTotal.Length, '0');
Int32 maxLength = sCurrent.Length;
if (maxLength > Int64.MaxValue.ToString().Length - 1)
maxLength = Int64.MaxValue.ToString().Length - 1;
UInt64 currentI = Convert.ToUInt64(sCurrent.Substring(0, maxLength));
UInt64 totalI = Convert.ToUInt64(sTotal.Substring(0, maxLength));
Percent = (Decimal)100.0 / totalI
* currentI;
Can you suggest better?
You're computing a rational, not an integer, so you should install the Solver Foundation:
http://msdn.microsoft.com/en-us/library/ff524509(v=VS.93).aspx
and use Rational rather than BigInteger:
http://msdn.microsoft.com/en-us/library/ff526610(v=vs.93).aspx
You can then call ToDouble if you want to get the rational as the nearest double.
I need it accurate to 56 decimal places
OK, that is a ridiculous amount of precision, but I'll take you at your word.
Since a double has only 15 decimal places of precision and a decimal only 29, you can't use double or decimal. You're going to have to write the code yourself to do the division.
Here are two ways to do it:
First, write an algorithm that emulates doing long division. You can do it by hand, so you can write a computer program to do it. Keep going until you generate the required number of bits of precision.
Second: WOLOG assume that the rational in question is positive and is of the form x / y where x and y are big integers. Let b be 10p for a desired precision p. You wish to find the big integer a with the property that:
a * y < b * x
and
b * x < (a + 1) * y
Either a/b or (a+1)/b is the decimal fraction with p digits closest to x/y.
Make sense?
You can find the value of a by doing a binary search over the set of non-negative BigIntegers.
To do the binary search, first you have to find upper and lower bounds. Lower is easy enough; you know that 0 is a lower bound because by assumption the fraction x/y is positive. To find the upper bound, try 1/b, 10/b, 100/b ... and so on until you find a value that is larger than x/y. Now you have an upper and lower bound, and you can binary search the resulting space to find the exact value of a that makes the inequalities true.