I want to calculate a percentage. My code is:
Bot.Log("[ KEYBOT ] The total is " + (suctrades * totaltrades ) / 100 + "% !");
If I do this, I only get 0. What am I doing wrong?
Probably suctrades * totaltrades is still an int. The easiest way will be probably changing your code to:
((double)suctrades) * totaltrades/100
Or
suctrades * totaltrades/100.0
To force using double instead of int
Try :
Bot.Log("[ KEYBOT ] The total is " + ((double)suctrades * totaltrades ) / 100 + "% !");
I assume suctrades and totaltrades are not of decimal type. This should fix this due to type propagation as expression is evaluated.
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.: 100.0m this is casting to decimal !
decimal result = suctrades * totaltrades/100.0m
Related
I wanted to ask a question about a calculation I had today in C#.
double expenses = (pricePen + priceMark + priceLitres) - discount / 100*(pricePen + priceMark + priceLitres); //Incorrect
double expenses = (pricePen + priceMark + priceLitres) - (pricePen + priceMark + priceLitres)* discount/100; //Correct
So as you can see at the end of the equation I had to multiply the brackets by the integer named "discount", which is obviously a discount percentage.
When I change the places of that value whether it would be in front of the brackets or behind the brackets the answer will always be different, but in Maths I even checked myself that I should get the same answer even if the value is placed in front of the brackets to multiply or placed behind the brackets to multiply again, but C# doesn't think so.
I wanted to ask people, how does C# actually calculate this and why am I getting different results at the end? (Result should be 28.5, not 38)
[Data: pricePen = 11.6; priceMark = 21.6; priceLitres = 4.8; discount = 25;]
(I know that the question is irrelevant.)
In first line after dividing by 100 the result is in an integer. For that the rest of division get lost. So the multiplication has a lower result.
In second line the multiplication has the correct result and the rest of devision is lower than one.
So I know its already answered but if you want to learn more about divisions with int
here it is:
for example:
float value = 3/4 you would expect it to be 0.75 but that's not the case.
Because when the Compiler goes through the values 3 and 4 he makes des Literal of the highest data type - in this case (int)-.
That means the result of this division will be "0".75 because int has no floating numbers and just cuts it off. Then the program just takes that value and puts it in the float value ...
so the result will be
"3/4" 0 ->"float value" 0.0 = 0.0
Some guys before me already told you the solution to that problem like making one divisor to float with .0
float value = 3.0/4
or you can tell the Compiler to store the value in a float Literal with the (float) "command"
float value = (float) 3/4
I hope it helped you explain why you did that :)
To avoid these problems makes sure you are doing math with floating point types, and not int types. In your case discount is an int and thus
x * (discount / 100) = x * <integer>
Best to define a function to do the calculation which forces the type
double DiscountedPrice(double price, double discount)
{
return price - (discount/100) * price;
}
and then call it as
var x = DiscountedPrice( pricePen + priceMark + priceLitres, 15);
In the above scenario, the compiler will force the integer 15 to be converted into an double as a widening conversion (double has more digits than integer).
I'm trying to cast the result of a divide result to an int in c#
This is my code:
decimal testDecimal = 5.00; // testDecimal always is dividable by 0.25 with 0 rest
int times=0;
int times = testDecimal / Convert.ToDecimal(0.250);
// error returned -> Cannot implicitly convert type 'decimal' to 'int'.
if I change my cast to
int times = (int) testDecimal / Convert.ToDecimal(0.250);
//also returns an error: Cannot implicitly convert type 'decimal' to 'int'
How could I get the result (20) as an integer? What am I doing wrong?
Try this:
times = (int)(testDecimal / Convert.ToDecimal(0.250));
Without the extra parenthesis, it is trying to convert ONLY testDecimal to integer, then trying to convert the int/decimal result to an integer implicitly, which is what causes the error.
In an unrelated note, you are trying to declare the variable 'times' twice.
As everybody answered, you have to add parenthesis to cast the result of the your division instead of just trying to cast the first part and then getting the error after the division.
I also want to point out that it is not necessary to use Convert.ToDecimal just to declare your constant as adecimal, you could use C# suffixs to do so:
int times = (int)(testDecimal / 0.250m);
You have to cast the whole division result. try like:
int times = (int) (testDecimal / Convert.ToDecimal(0.250));
Be careful though because this could suffer the seemingly random floating point arithmetic error depending on which values you use.
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
You may avoid this by first rounding the value.
(int) Math.Round(testDecimal / Convert.ToDecimal(0.250));
first you don't need to do convert to decimal, you can just do 0.25m
and then you can do
times = (int) (testDecimal / 0.25m);
do note that if the number is too big this might give you wrong result.
If you want a numeric literal to be treated as decimal, use the suffix m or M. By this way there is no need to use Convert.ToDecimal.
decimal testDecimal = 5.00M;
int times = (int)(testDecimal / 0.250M);
First of all you should add "M" suffix to your testDecimal declaration otherwise your 5.00 is a litteral and not a decimal.
decimal testDecimal = 5.00M;
Now, your compiler is not aware that your division result is an integer. Even if your devision can be casted to "int", for him, a decimal devided by another is a decimal and not an integer. You have to implicitly cast it:
int times = (int)(testDecimal / 0.250M);
Works like charm for me.
Wrap your expression in parenthesis so that you can convert it:
// int times = (int)testDecimal / 0.250m;
int times = (int)(testDecimal / 0.250m);
Just a note, make sure you are try/catching while converting because not all decimal values can fit into int.
try
{
times = (int)decimal.MaxValue;
}
catch(OverflowException ex)
{
// Value was either too large or too small for an Int32.
}
I'm not sure why you have Convert.ToDecimal(0.250). Why convert the float (0.250) to a decimal at run time? Why not just use a decimal literal (like 0.25M)? As other folks have noted, you need to cast the results of the division to an int, like:
decimal testDecimal = 5M;
int times = (int) (testDecimal / 0.25M);
Assert.AreEqual(20, times);
Also, as other folks have noted, you may want to think through how you do your conversion from decimal to int. Do you want to the default behavior (what you get from a simple cast), or do you want round up, round down, round to even, etc.? In this case, since the division yields an integral result, it doesn't matter, but in the general case, you'll want to put some thought into it.
By the way, the reason you have an error in this code:
int times = (int) testDecimal / Convert.ToDecimal(0.250);
is that you are casting testDecimal (5.0M) to an int (5). Then you are dividing it by a decimal (0.25M), which yields a decimal (20.0M). Finally, you are trying to assign that decimal to an integer, and the compiler signals an error.
HTH
I was just curious if anyone could explain to me why these different data types round differently in my code? (note: this is not how the variables are actually declared, it is how they are stored. I just displayed them like this for clarity)
double amount = 15 ;
double taxPercentage = 0.015;
decimal itemTax;
First, the un-rounded result:
itemTax = (decimal)(amount * taxPercentage);
// itemTax returns -0.225
If I round first, then cast to decimal:
itemTax = (decimal)(Math.Round(amount * taxPercentage, 2, MidpointRounding.AwayFromZero));
// itemTax returns -0.22
If I cast to decimal first, then round:
itemTax = (decimal)(amount * taxPercentage);
itemTax = Math.Round(itemTax,2,MidpointRounding.AwayFromZero);
// itemTax returns -0.23
Does this have something to do with the way double types round vs. decimal types?
Indeed. Double (like float) is base-2 number and is actually an approximation of a decimal value. Unlike decimal values, it can't represent infinite precision numbers so your -0.025 values might really be -0.024999999999
Why is the output "0 and 0"? How do I fix it?
Int64 small= (long)0.25 * (long)Int64.MaxValue;
Int64 large = (long)0.75 * (long)Int64.MaxValue;
System.Console.WriteLine(small + " and " + large);
System.Console.ReadLine();
//output
//0 and 0
Statement (long)0.75 will return 0 (converting double to long will take greatest integer value, that is lower that converting double). So you have 0 * 9223372036854775807 which is hopefully 0. By the way long is alias for Int64, which means they are the same underlying types, so by (long)Int64.MaxValue you casting long to long
to fix it simply use double * long multiplication
long small= (long)(0.25 * long.MaxValue);
long large = (long)(0.75 * long.MaxValue);
Console.WriteLine ("{0:N}", small); //print 2,305,843,009,213,693,952.00
Console.WriteLine ("{0:N}", large); //print 6,917,529,027,641,081,856.00
don't bother with "{0:N}" literal, it's simply a format to give the output some visual beauty. By default double is printed in scientific notation, which is not so demonstrable (for example 2.30584300921369E+18 for first operation)
The reason why is that in both cases you are converting a value which is less than 1 to a long. This will truncate the value to 0 hence the multiplication also results in 0
Console.WriteLine((long)0.25); // 0
Console.WriteLine((long)0.75); // 0
Because 0.25 and 0.75 casted as long are 0.
In order to remedy that, you will need to use floats or doubles. However, I'm not 100% certain the precision is enough to lead to exact results:
Int64 small= (Int64)(0.25 * (double)Int64.MaxValue);
Int64 large = (Int64)(0.75 * (double)Int64.MaxValue);
You want to convert after not before the multiplication. Try
Int64 small= (long) (0.25 * (double) Int64.MaxValue);
Before you were converting .25 to long which is 0.
I'm trying to subtract percentage in C# using:
n = n - (n * 0.25);
but I'm getting an error:
"Cannot implicitly 'double' to 'int'. An explicit conversions exists
(are you missing a cast?)"
Your value n is an int.
When you multiply by 0.25( which is a double), the resulting value is a double that you try to assign to a int.
To solve it, you have to specify that you are aware that you will lose precision using "explicit conversion".
n = n - (int)(n * 0.25);
Doing (Type)value is called "to cast value to Type". This is exactly what the error message suggest you to do.
Or, if you don't want to keep the precision, declare n not as an int but as a double. In this case, you will not have to cast n * 0.25 to int.
If you don't want to switch back and forwards between int and double types you could just use:
n = (n * 75) / 100
if your answer ever has decimals they'll be lost though
Your variable n must be an integer, but the result of your calculation is a double, since it involves multiplication by a double (0.25).
You can cast the result back to an int like this:
n = (int)(n - (n * 0.25));
I'm assuming that n is an integer type then, say int, as you don't give a clue to that. In which case the easiest solution is to do:
n = Convert.ToInt32(n - (n * 0.25));
Or you can cast:
n = (int)(n - (n * 0.25));
Check the type of variable 'n'.
Either 'n' should be of double type.
Or
Use explicit cast to convert to int.
int n = (int)(n - (n * 0.25));
you must cast result to int
n=(int)(n-(n*0.25));
try:
n = n - (int)((double)n * 0.25);
note: by doing this you wont have numbers behind the point in the n result.
I guess this could be an issue with the type of n being int it least needs to be double
hence when you have n = n - (n * 0.25) the result is a double
if you want to cast it as int then beware of rounding since it would not always be ending in .00
Also i think this would be better n = n * 0.75
Your n variable is an int. When you try to multiple with 0.25, 0.25 is double, so result will be double. You should cast it manually because there is no Implicit Numeric Conversion for double to int. You have to use Explicit Numeric Conversion for them.
From --> To
double --> sbyte , byte, short, ushort, int, uint, long, ulong, char, float, or decimal
You should convert your right expression to int.
int n = 100;
n = (int) (n - (n * 0.25));
Console.WriteLine(n);
Here is a DEMO.
And remember;
Explicit numeric conversion may cause loss of precision.
When you convert from a double value to an integral type, the value is truncated. If the resulting integral value is outside the range of the destination value, the result depends on the overflow checking context.
The best way would be to do
n = n - n/4;
If you want a percentage to be a whole number between 0 and 100, otherwise you should declare n to be a double by replacing int n with double n.
No costly conversion will occur in the proposed assignment. Note that n/4 is an integer because both operands (n and 4) are integers, causing no promotions, thus using integer division.
Explanation
This is type promotion, n is multiplied by a double, which promotes n*0.25 automatically to a double. A primitive can only be promoted into a higher rank, not demoted to a lower rank. A primitive x is of a higher rank then another primitive y if it can hold all values of y without causing loss of precision. A double can hold all values of an integer, but an integer can, for example, not hold 0.1. So you are trying to promote and demote. See MSDN library for more information.
Note:
Casting from a double to an int causes the value to be truncated, that is all decimals after the 'dot' will be erased, so -2.5 becomes -2 and 1.5 becomes 1. Integer division, as used above also rounds to zero, making this assignment equal with your assignment. But avoiding any costly conversions.