Why different result in same operation? PHP e C# - c#

I have the following operation in PHP:
24733 * 0x41c64e6d + 0x6073;
...and the result is: 27293242579276
With the same logic, I do the same operation in C#:
24733 * 0x41c64e6d + 0x6073;
But the result is: -1274586804
OMG, why?

by default c# treats number as int when no explicit cast is specified.
so 24733 is treated as int.
int x int + int = int
and Max int is 2147483647 which is way smaller than 27293242579276. This resulted in integer overflow.
To solve the problem, use a type with higher number of bits such as decimal
you can append a letter "m" at the end of the number to tell c# you want it to be a decimal
like 24733m * 0x41c64e6d + 0x6073

In PHP here's what's happening
int(24733) *
int(1103515245) +
int(24691)
You can see this by doing a var_dump of the values
In 64-bit builds, the maximum integer is 9223372036854775807. So PHP can support the provided answer of 27293242579276. Based on the other answer, it looks like C# just converts the numbers differently, and possibly with a lower maximum integer.

Related

Convert 2 integers to float number

I need to convert 2 integers to a float number. I'm using the following function to do this conversion:
string hexString = value1 + value2;
uint num = uint.Parse(hexString, NumberStyles.AllowHexSpecifier);
byte[] floatVals = BitConverter.GetBytes(num);
f = BitConverter.ToSingle(floatVals, 0);
The function works fine, except when the second integer is negative. Which gives a small difference in the decimal part.
Example:
16998 and 16673: 57.76 -> Correct
16998 and -11174: 57.54 -> Incorrect (The correct is: 57.71).
What I'm doing to get close to the correct number is multiplying the second integer by -1 to make it positive. My question is how to get the exact value when the second integer is negative?
Reading the manual, it says:
Myy app screenshot:

Divide two decimals and cast result to int

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

How to (theoretically) print all possible double precision numbers in C#?

For a little personal research project I want to generate a string list of all possible values a double precision floating point number can have.
I've found the "r" formatting option, which guarantees that the string can be parsed back into the exact same bit representation:
string s = myDouble.ToString("r");
But how to generate all possible bit combinations? Preferably ordered by value.
Maybe using the unchecked keyword somehow?
unchecked
{
//for all long values
myDouble[i] = myLong++;
}
Disclaimer: It's more a theoretical question, I am not going to read all the numbers... :)
using unsafe code:
ulong i = 0; //long is 64 bit, like double
unsafe
{
double* d = (double*)&i;
for(;i<ulong.MaxValue;i++)
Console.WriteLine(*d);
}
You can start with all possible values 0 <= x < 1. You can create those by having zero for exponent and use different values for the mantissa.
The mantissa is stored in 52 bits of the 64 bits that make a double precision number, so that makes for 2 ^ 52 = 4503599627370496 different numbers between 0 and 1.
From the description of the decimal format you can figure out how the bit pattern (eight bytes) should be for those numbers, then you can use the BitConverter.ToDouble method to do the conversion.
Then you can set the first bit to make the negative version of all those numbers.
All those numbers are unique, beyond that you will start getting duplicate values because there are several ways to express the same value when the exponent is non-zero. For each new non-zero exponent you would get the value that were not possible to express with the previously used expontents.
The values between 0 and 1 will however keep you busy for the forseeable future, so you can just start with those.
This should be doable in safe code: Create a bit string. Convert that to a double. Output. Increment. Repeat.... A LOT.
string bstr = "01010101010101010101010101010101"; // this is 32 instead of 64, adjust as needed
long v = 0;
for (int i = bstr.Length - 1; i >= 0; i--) v = (v << 1) + (bstr[i] - '0');
double d = BitConverter.ToDouble(BitConverter.GetBytes(v), 0);
// increment bstr and loop

How to calculate a percentage

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

C# double, decimal problems

Why does this calcuation: double number = (13 /(13+12+13))
equals 0?
It should be around 0.34, I think!
Thanks!
Because you are dividing an int with an int. You should be doing
double number = (13.0 /(13.0+12.0+13.0));
That are integers. So it does integer division. And thus truncates to the next lower(closer to 0) integer.
Add a .0 to a number like 13.0 to make it a double.
Because you're using all INT in your formula - it will be treated as INT for the result too.
Try this instead:
var result = 13.0 / (13.0 + 12.0 + 13.0)
and your result will be:
0.34210526315789475
Try adding a .0:
(13.0 /(13+12+13))
Otherwise you're dealing with integers.
Another option is to cast one of the arguments explicitly to double and thus forcing the runtime to perform double division. e.g. :
double result = ((double)13 / (13 + 12 + 13));
Adding a ".0" will help:
double number = (13.0 /(13.0+12.0+13.0));

Categories

Resources