confusion with result of Ushort - c#

consider the following code :
ushort a = 60000;
a = (ushort)(a * a / a);
Console.WriteLine("A = " + a);
//This prints 53954. Why??
and
ushort a = 40000;
a = (ushort)(a * a / a);
Console.WriteLine("a = " + a.ToString());
//This prints 40000. how??
any help appreciable ...

Because 60000^2 is 3600000000 but the biggest number an int can hold is 2,147,483,647, so it starts over from -2,147,483,648.
A ushort can hold 65,535 and then starts over from 0:
For instance, this prints 0:
ushort myShort = 65535;
myShort++;
Console.WriteLine(myShort); //0
It's easier to see this if you break it into steps:
var B = A * A;
That actually exceeds the capacity of an int32, so it starts from -2,147,483,648 thus b equals -694967296
Then when you split B/A you get: -11582 which, when cast into a ushort becomes 53954.
ushort A = 60000;
var B = A * A; //-694967296
var C = B / A; //-11582
ushort D = (ushort)(C); //53954
The reason that 40000 works is that it does not exceed the capacity of an int32.
ushort A = 40000;
var B = A * A; //1600000000
var C = B / A; //40000
ushort D = (ushort)(C); //40000
uint can hold 60000^2 though, so this works:
ushort A = 60000;
var B = (uint)A * A; //3600000000
var C = B / A; //60000
ushort D = (ushort)(C); //60000
The reason that casting C to ushort yeilds 53954 is because the bytes of C is:
96
234
0
0
And the bytes of D is:
96
234
So they hold the same backing bytes, that's why you get 53954 and -11582

Because it's equivalent to
A * A = -694967296 because the result ends up as an int, and overflow on the short gives a bit pattern that yields this negative result. Ultimately 60000 * 60000 can't be stored in a ushort. Add a watch in debug mode and you'll see this.
Then you have
-694967296 / 60000 - which yields -11582 as an int, but when cast to a ushort yields 53954 - again because of the underlying bit pattern.
Really, this code would need to be in a checked block because it's for this very reason that overflow errors cause massive issues.

First good Question! Now let me tell you one thing If you try 40000 it will work fine.
the reason is that (40000 ^ 2) that is the highest limit of ushort so it will convert into integer so it will not truncate !
If you use 60000 it will ! Due to limit restriction !
Try it with 40000 !
Hope you get my answer

Related

C# Bitwise XOR two very large hex numbers

I have two hex numbers, which, for the purposes of experimenting with OTP, I'm trying to XOR with C#. Unfortunately, both numbers are on the order of hundreds of digits - clearly far too large to store in an int or long. How do I store/XOR them? Right now, I'm storing as BigIntegers like so:
public static string XOR(string string_1, string string_2){
BigInteger b1 = BigInteger.Parse(string_1, System.Globalization.NumberStyles.AllowHexSpecifier);
BigInteger b2 = BigInteger.Parse(string_2, System.Globalization.NumberStyles.AllowHexSpecifier);
BigInteger retVal = b1 ^ b2;
return retVal.ToString("X");
}
which isn't producing the expected result. Thanks!
EDIT:
Input:
string_1 = 32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba7696cf606ef40c04afe1ac0aa8148dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce
string_2 = 71946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027
Expected result (according to Python and this online XOR calculator):
32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5b83624730b208d83b237176b5a41e13d1a2c0080f55d6fb05e4fd9a6e8aff84a9eec74ec0e3115dd0808c011baa15b2c29edad06d6c319976fc7c7eb6a8727e79906c96397dd14594a17511e2ba018c3267935877b5c2c1750f28b2d5bf55faa6c2218c30e58f17542717ad6f8622dd0069a4886d20d3d657a80a869c8f6025399f914f23e5ccd3a999c271a50994c7db959c5c0b73334d15ba3754e9
Seems somebody doesn't want to believe.
var string_1 = "32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba7696cf606ef40c04afe1ac0aa8148dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce";
var string_2 = "71946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027";
//copied from https://xor.pw/?
string expectedResult = "32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba3624730b208d83b237176b5a41e13d1a2c0080f55d6fb05e4fd9a6e8aff84a9eec74ec0e3115dd0808c011baa15b2c29edad06d6c319976fc7c7eb6a8727e79906c96397dd14594a17511e2ba018c3267935877b5c2c1750f28b2d5bf55faa6c2218c30e58f17542717ad6f8622dd0069a4886d20d3d657a80a869c8f6025399f914f23e5ccd3a999c271a50994c7db959c5c0b73334d15ba3754e9";
BigInteger b1 = BigInteger.Parse(string_1, NumberStyles.HexNumber);
BigInteger b2 = BigInteger.Parse(string_2, NumberStyles.HexNumber);
BigInteger retVal = b1 ^ b2;
var res = retVal.ToString("X").ToLower() == expectedResult;
Guess the res in answer. Of course TRUE. :)

C# Getting the last 10 bits of a 32 bit uint

I'm looking to get the last 10 bits of a 32 Bit integer,
Essentially what I did was take a number and jam it into the first 22 bits, I can extract that number back out quite nicely with
int test = Convert.ToInt32(uIActivityId >> nMethodBits); //method bits == 10 so this just pushes the last ten bits off the range
Where test results in the number I put in in the first place.
But now I'm stumped. So my question to you guys is. How do i get the last ten bits of a 32 bit integer?
First create a mask that has a 1 bit for those bits you want and a 0 bit for those you're not interested in. Then use binary & to keep only the relevant bits.
const uint mask = (1 << 10) - 1; // 0x3FF
uint last10 = input & mask;
This one is another try !!
List<bool> BitsOfInt(int input , int bitCount)
{
List<bool> outArray = new BitArray (BitConverter.GetBytes(input)).OfType<bool>().ToList();
return outArray.GetRange(outArray.Count - bitCount, bitCount);
}
int i = Convert.ToInt32("11100111101", 2);
int mask = Convert.ToInt32("1111111111", 2);
int test = Convert.ToInt32(( i&mask));
int j = Convert.ToInt32("1100111101", 2);
if (test == j)
System.Console.Out.WriteLine("it works");
public bool[] GetLast10Bits(int input) {
BitArray array = new BitArray(new []{input});
List<bool> bits = new List<bool>();
if (array.Length > 10) {
return Enumerable.Range(0, 10).Select(i => array[i]).ToArray();
}
return new bool[0];
}

expressing hex value in 2's complement

i have a string hex value, and i need to express it in 2's complement.
string hx = "FF00";
what i did is, converting it to binary:
string h = Convert.ToString(Convert.ToInt32(hx, 16), 2 );
then inverting it, but i couldn't use the NOT operator.
is there any short way to invert the bits and then adding 1 (2's complement operation)?
The answer might depend on whether or not the bit width of the value is important to you.
The short answer is:
string hx = "FF00";
uint intVal = Convert.ToUInt32(hx, 16); // intVal == 65280
uint twosComp = ~v + 1; // twosComp == 4294902016
string h = string.Format("{0:X}", twosComp); // h == "FFFF0100"
The value of h is then "FFFF0100" which is the 32-bit 2's complement of hx. If you were expecting '100' then you need to use 16-bit calculations:
string hx = "FF00";
ushort intVal = Convert.ToUInt16(hx, 16); // intVal = 65280
ushort twosComp = (ushort)(~v + 1); // twosComp = 256
string h = string.Format("{0:X}", twosComp); // h = "100"
Bear in mind that uint is an alias for UInt32 and ushort aliases the UInt16 type. For clarity in this type of operation you'd probably be better off using the explicit names.
Two complment is really simple:
int value = 100;
value = ~value // NOT
value = value + 1;
//Now value is -100
Remember that a two complement system requires inverting and adding plus 1.
In hex:
int value = 0x45;
value = ~value // NOT
value = value + 1;

conversion BigDecimal Java to c#-like Decimal

In Java BigDecimal class contains values as A*pow(10,B) where A is 2's complement which non-fix bit length and B is 32bit integer.
In C# Decimal contains values as pow (–1,s) × c × pow(10,-e) where the sign s is 0 or 1, the coefficient c is given by 0 ≤ c < pow(2,96) , and the scale e is such that 0 ≤ e ≤ 28 .
And i want to convert Java BigDecimal to Something like c# Decimal in JAVA.
Can you help me .
I have some thing like this
class CS_likeDecimal
{
private int hi;// for 32bit most sinificant bit of c
private int mid;// for 32bit in the middle
private int lo;// for 32 bit the last sinificant bit
.....
public CS_likeDecimal(BigDecimal data)
{
....
}
}
In fact I found this What's the best way to represent System.Decimal in Protocol Buffers?.
it a protocol buffer for send c# decimal ,but in the protobuff-net project use this to send message between c# (but i want between c# and JAVA)
message Decimal {
optional uint64 lo = 1; // the first 64 bits of the underlying value
optional uint32 hi = 2; // the last 32 bis of the underlying value
optional sint32 signScale = 3; // the number of decimal digits, and the sign
}
Thanks,
the Decimal I use in protobuf-net is primarily intended to support the likely usage of protobuf-net being used at both ends of the pipe, which supports a fixed range. It sounds like the range of the two types in discussion is not the same, so: are not robustly compatible.
I would suggest explicitly using an alternative representation. I don't know what representations are available to Java's BigDecimal - whether there is a pragmatic byte[] version, or a string version.
If you are confident that the scale and range won't be a problem, then it should be possible to fudge between the two layouts with some bit-fiddling.
I needed to write a BigDecimal to/from .Net Decimal converter.
Using this reference:
http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx
I wrote this code that could works:
public static byte[] BigDecimalToNetDecimal(BigDecimal paramBigDecimal) throws IllegalArgumentException
{
// .Net Decimal target
byte[] result = new byte[16];
// Unscaled absolute value
BigInteger unscaledInt = paramBigDecimal.abs().unscaledValue();
int bitLength = unscaledInt.bitLength();
if (bitLength > 96)
throw new IllegalArgumentException("BigDecimal too big for .Net Decimal");
// Byte array
byte[] unscaledBytes = unscaledInt.toByteArray();
int unscaledFirst = 0;
if (unscaledBytes[0] == 0)
unscaledFirst = 1;
// Scale
int scale = paramBigDecimal.scale();
if (scale > 28)
throw new IllegalArgumentException("BigDecimal scale exceeds .Net Decimal limit of 28");
result[1] = (byte)scale;
// Copy unscaled value to bytes 8-15
for (int pSource = unscaledBytes.length - 1, pTarget = 15; (pSource >= unscaledFirst) && (pTarget >= 4); pSource--, pTarget--)
{
result[pTarget] = unscaledBytes[pSource];
}
// Signum at byte 0
if (paramBigDecimal.signum() < 0)
result[0] = -128;
return result;
}
public static BigDecimal NetDecimalToBigDecimal(byte[] paramNetDecimal)
{
int scale = paramNetDecimal[1];
int signum = paramNetDecimal[0] >= 0 ? 1 : -1;
byte[] magnitude = new byte[12];
for (int ptr = 0; ptr < 12; ptr++) magnitude[ptr] = paramNetDecimal[ptr + 4];
BigInteger unscaledInt = new BigInteger(signum, magnitude);
return new BigDecimal(unscaledInt, scale);
}

Adding byte[] interpreted as a number and short

I want to add a byte array to a short var.
Can any one suggest how to do using bit wise operators.
For example:
byte[] a = new byte[] { 0x02,0x11 }; //Dec eq is 529
short b = 10;
I want the result to be 539.
b += ((short) a[0]) << 8;
b += a[1];
I know you have a byte array and not a BitArray, but maybe this helps.
short c = (short)(BitConverter.ToInt16(a, 0) + b);

Categories

Resources