Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I just started coding in C++ and I saw in some example codes this symbol: <<
is there a equavalent in C# if so What is it?
Thank you in advance.
Disclaimer: I don't know anything about C#; this answer just describes the operator in C++.
It depends on context; that operator is often overloaded to mean different things for different types.
For integer types, it's the bitwise left shift operator; it takes the bit pattern of a value, and moves it to the left, inserting zero into the less significant bits:
unsigned x = 6; // decimal 6, binary 00110
unsigned y = x << 2; // decimal 24, binary 11000
In general, a left-shift by N bits is equivalent to multiplying by 2N (so here, shifting by 2 bits multiplies by 4).
I'm fairly sure this use of the operator is the same in C# as in C++.
The standard library overloads the operator to insert a value into an output stream, in order to produce formatted output on the console, or in files, or in other ways.
#include <iostream> // declare standard input/output streams
std::cout << 42 << std::endl; // print 42 to the console, end the line, and flush.
I think C# has a TextWriter or something to handle formatted output, with Console.Out or something being equivalent to std::cout; but C# uses normal method calls rather than an overloaded operator.
operator<< means exactly the same in C++ as it does in C#; it is the left-shift operator and moves all the bits in a number one bit to the left.
But, in C++, you can overload most operators to make them do whatever you like for user-defined types. Perhaps most commonly, the left- and right-shift operators are overloaded for streams to mean 'stuff this thing into that stream' (left-shift) or 'extract a variable of this type from that stream' (right-shift).
Related
When I Initialize a ulong with the value 18446744073709551615 and then add a 1 to It and display to the Console It displays a 0 which is totally expected.
I know this question sounds stupid but I have to ask It. if my Computer has a 64-bit architecture CPU how is my calculator able to work with larger numbers than 18446744073709551615?
I suppose floating-point has a lot to do here.
I would like to know exactly how this happens.
Thank you.
working with larger numbers than 18446744073709551615
"if my Computer has a 64-bit architecture CPU" --> The architecture bit size is largely irrelevant.
Consider how you are able to add 2 decimal digits whose sum is more than 9. There is a carry generated and then used when adding the next most significant decimal place.
The CPU can do the same but with base 18446744073709551616 instead of base 10. It uses a carry bit as well as a sign and overflow bit to perform extended math.
I suppose floating-point has a lot to do here.
This is nothing to do with floating point.
; you say you're using ulong, which means your using unsigned 64-but arithmetic. The largest value you can store is therefore "all ones", for 64 bits - aka UInt64.MaxValue, which as you've discovered: https://learn.microsoft.com/en-us/dotnet/api/system.uint64.maxvalue
If you want to store arbitrarily large numbers: there are APIs for that - for example BigInteger. However, arbitrary size cones at a cost, so it isn't the default, and certainly isn't what you get when you use ulong (or double, or decimal, etc - all the compiler-level numeric types have fixed size).
So: consider using BigInteger
You either way have a 64 bits architecture processor and limited to doing 64 bits math - your problem is a bit hard to explain without taking an explicit example of how this is solved with BigInteger in System.Numerics namespace, available in .NET Framework 4.8 for example. The basis is to 'decompose' the number into an array representation.
mathematical expression 'decompose' here meaning :
"express (a number or function) as a combination of simpler components."
Internally BigInteger uses an internal array (actually multiple internal constructs) and a helper class called BigIntegerBuilder. In can implicitly convert an UInt64 integer without problem, for even bigger numbers you can use the + operator for example.
BigInteger bignum = new BigInteger(18446744073709551615);
bignum += 1;
You can read about the implicit operator here:
https://referencesource.microsoft.com/#System.Numerics/System/Numerics/BigInteger.cs
public static BigInteger operator +(BigInteger left, BigInteger right)
{
left.AssertValid();
right.AssertValid();
if (right.IsZero) return left;
if (left.IsZero) return right;
int sign1 = +1;
int sign2 = +1;
BigIntegerBuilder reg1 = new BigIntegerBuilder(left, ref sign1);
BigIntegerBuilder reg2 = new BigIntegerBuilder(right, ref sign2);
if (sign1 == sign2)
reg1.Add(ref reg2);
else
reg1.Sub(ref sign1, ref reg2);
return reg1.GetInteger(sign1);
}
In the code above from ReferenceSource you can see that we use the BigIntegerBuilder to add the left and right parts, which are also BigInteger constructs.
Interesting, it seems to keep its internal structure into an private array called "_bits", so that is the answer to your question. BigInteger keeps track of an array of 32-bits valued integer array and is therefore able to handle big integers, even beyond 64 bits.
You can drop this code into a console application or Linqpad (which has the .Dump() method I use here) and inspect :
BigInteger bignum = new BigInteger(18446744073709551615);
bignum.GetType().GetField("_bits",
BindingFlags.NonPublic | BindingFlags.Instance).GetValue(bignum).Dump();
A detail about BigInteger is revealed in a comment in the source code of BigInteger on Reference Source. So for integer values, BigInteger stores the value in the _sign field, for other values the field _bits is used.
Obviously, the internal array needs to be able to be converted into a representation in the decimal system (base-10) so humans can read it, the ToString() method converts the BigInteger to a string representation.
For a better in-depth understanding here, consider doing .NET source stepping to step way into the code how you carry out the mathematics here. But for a basic understanding, the BigInteger uses an internal representation of which is composed with 32 bits array which is transformed into a readable format which allows bigger numbers, bigger than even Int64.
// For values int.MinValue < n <= int.MaxValue, the value is stored in sign
// and _bits is null. For all other values, sign is +1 or -1 and the bits are in _bits
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Does C# have a 4 bit data type? I want to make a program with variables that waste the minimum amount of memory, because the program will consume a lot.
For example: I need to save a value that i know it will go from 0 to 10 and a 4 bit var can go from 0 to 15 and it's perfect. But the closest i found was the 8 bit (1 Byte) data type Byte.
I have the idea of creating a c++ dll with a custom data type. Something like nibble. But, if that's the solution to my problem, i don't know where to start, and what i have to do.
Limitations: Creating a Byte and splitting it in two is NOT an option.
No, there is no such thing as a four-bit data type in c#.
Incidentally, four bits will only store a number from 0 to 15, so it doesn't sound like it is fit for purpose if you are storing values from 0 to 127. To compute the range of a variable given that it has N bits, use the formula (2^N)-1 to calculate the maximum. 2^4 = 16 - 1 = 15.
If you need to use a data type that is less than 8 bits in order to save space, you will need to use a packed binary format and special code to access it.
You could for example store two four-bit values in a byte using an AND mask plus a bit shift, e.g.
byte source = 0xAD;
var hiNybble = (source & 0xF0) >> 4; //Left hand nybble = A
var loNyblle = (source & 0x0F); //Right hand nybble = D
Or using integer division and modulus, which works well too but maybe isn't quite as readable:
var hiNybble = source / 16;
var loNybble = source % 16;
And of course you can use an extension method.
static byte GetLowNybble(this byte input)
{
return input % 16;
}
static byte GetHighNybble(this byte input)
{
return input / 16;
}
var hiNybble = source.GetHighNybble();
var loNybble = source.GetLowNybble();
Storing it is easier:
var source = hiNybble * 16 + lowNybble;
Updating just one nybble is harder:
var source = source & 0xF0 + loNybble; //Update only low four bits
var source = source & 0x0F + (hiNybble << 4); //Update only high bits
A 4-bit data type (AKA Nib) only goes from 0-15. It requires 7 bits to go from 0-127. You need a byte essentially.
No, C# does not have a 4-bit numeric data type. If you wish to pack 2 4-bit values in a single 8-bit byte, you will need to write the packing and unpacking code yourself.
No, even boolean is 8 bits size.
You can use >> and << operators to store and read two 4 bit values from one byte.
https://msdn.microsoft.com/en-us/library/a1sway8w.aspx
https://msdn.microsoft.com/en-us/library/xt18et0d.aspx
Depending on how many of your nibbles you need to handle and how much of an issue performance is over memory usage, you might want to have a look at the BitArray and BitVector32 classes. For passing around of values, you'd still need bigger types though.
Yet another option could also be StructLayout fiddling, ... beware of dragons though.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
As you can see here I have an unsigned variable and a signed one both with the same binary values but different decimal results.
uint unsigned = 0xFFFFFFFF; // 4,294,967,295
int signed = 0xFFFFFFFF; // -1
I am really confused! How does the machine make the difference between signed and unsigned , after all those are 32/64 bits all turned on. Is there a CPU flag that is used exactly for this? How does the CPU know the difference between a unsigned and a signed number? Trying to understand the concept for hours!
Or... another example...let's take 4 bits:
// 1 1 0 1 <--- -3
// 0 0 1 0 <--- 2
If we subtract 2 from -3 the result will be:
// 1 0 0 1 <--- -1 or 9???
The cpu will yield that result, but how does my application know that it is a -1 or a 9? It is known at compile time the expected result type?
another example...
int negative = -1;
Console.WriteLine(negative.ToString("X")); //output FFFFFFFF
uint positive = 0xFFFFFFFF;
Console.WriteLine(positive.ToString("X")); //output FFFFFFFF
later edit :
I messed up a little more with this stuff and I think I got it and please correct me if I am wrong:
We have the following example:
sbyte positive = 15; //0xF ( 0000 1111)
sbyte negative = unchecked((sbyte)-positive); //0xF01;( 1111 0001)
sbyte anotherPositive = 7; //0x7 ( 0000 0111)
sbyte result = (sbyte)(negative + anotherPositive);
//The cpu will add the numbers 1111 0001
// 0000 0111
// 1111 1000
// (Addition result is 248 but our variable is
//SIGNED and we have the sign bit ON(1) so the the value will be interpreted as -8)
I am really confused! How does the machine make the difference between at low level , after all those are 32 bits all turned on.
Machine doesn't; the compiler does. It is the compiler that knows the type of signed and unsigned variables (ignoring for a moment the fact that both signed and unsigned are keywords in C and C++). Therefore, the compiler knows what instructions to generate and what functions to call based on these types.
The distinction between the types is made at compile time, changing the interpretation of possibly identical raw data based on its compile-time type.
Consider an example of printing the value of a variable. When you write
cout << mySignedVariable << " " << myUnsignedVariable << endl;
the compiler sees two overloads of << operator being applied:
The first << makes a call to ostream& operator<< (int val);
The second << makes a call to ostream& operator<< (unsigned int val);
Once the code reaches the proper operator implementation, you are done: the code generated for the specific overload has the information on how to handle the signed or unsigned value "baked into" its machine code. The implementation that takes an int uses signed machine instructions for comparisons, divisions, multiplications, etc. while the unsigned implementation uses different instructions, producing the desired results.
It's the job of the language's type system to interpret what it sees.
All the CPU really sees is a bunch of zeros and ones.
Interestingly, two's complement arithmetic can use the same instructions as unsigned arithmetic. One's complement arithmetic requires an annoying complementing subtractor.
the computer doesn't care, as far as its concerned they are both the same, its the compiler and language structure running on the computer that decides how to interpret and handle the bit array and they know if its a uint, int, double, single, unicode char etc.
that's why managed memory is so important, if your program writes a uint to a memory address and another program reads it an a char then you get all sorts of strange behaviour, this can been seen when you open a binary file in notepad
I just found an interesting problem between translating some data:
VB.NET: CByte(4) << 8 Returns 4
But C#: (byte)4 << 8 Returns 1024
Namely, why does VB.NET: (CByte(4) << 8).GetType() return type {Name = "Byte" FullName = "System.Byte"}
Yet C#: ((byte)4 << 8).GetType() returns type {Name = "Int32" FullName = "System.Int32"}
Is there a reason why these two treat the binary shift the same? Following from that, is there any way to make the C# bit shift perform the same as VB.NET (to make VB.NET perform like C# you just do CInt(_____) << 8)?
According to http://msdn.microsoft.com/en-us/library/a1sway8w.aspx byte does not have << defined on it for C# (only int, uint, long and ulong. This means that it will use an implciit conversion to a type that it can use so it converts it to int before doing the bit shift.
http://msdn.microsoft.com/en-us/library/7haw1dex.aspx says that VB defines the operation on Bytes. To prevent overflow it applies a mask to your shift to bring it within an appropriate range so it is actually in this case shifting by nothing at all.
As to why C# doesn't define shifting on bytes I can't tell you.
To actually make it behave the same for other datatypes you need to just mask your shift number by 7 for bytes or 15 for shorts (see second link for info).
To apply the same in C#, you would use
static byte LeftShiftVBStyle(byte value, int count)
{
return (byte)(value << (count & 7));
}
as for why VB took that approach.... just different language, different rules (it is a natural extension of the way C# handles shifting of int/&31 and long/&63, to be fair).
Chris already nailed it, vb.net has defined shift operators for the Byte and Short types, C# does not. The C# spec is very similar to C and also a good match for the MSIL definitions for OpCodes.Shl, Shr and Shr_Un, they only accept int32, int64 and intptr operands. Accordingly, any byte or short sized operands are first converted to int32 with their implicit conversion.
That's a limitation that the vb.net compiler has to work with, it needs to generate extra code to make the byte and short specific versions of the operators work. The byte operator is implemented like this:
Dim result As Byte = CByte(leftOperand << (rightOperand And 7))
and the short operator:
Dim result As Short = CShort(leftOperand << (rightOperand And 15))
The corresponding C# operation is:
Dim result As Integer = CInt(leftOperand) << CInt(rightOperand)
Or CLng() if required. Implicit in C# code is that the programmer always has to cast the result back to the desired result type. There are a lot of SO questions about that from programmers that don't think that's very intuitive. VB.NET has another feature that makes automatic casting more survivable, it has overflow checking enabled by default. Although that's not applicable to shifts.
I'm porting several thousand lines of cryptographic C# functions to a Java project. The C# code extensively uses unsigned values and bitwise operations.
I am aware of the necessary Java work-arounds to support unsigned values. However, it would be much more convenient if there were implementations of unsigned 32bit and 64bit Integers that I could drop into my code. Please link to such a library.
Quick google queries reveal several that are part of commercial applications:
http://www.teamdev.com/downloads/jniwrapper/javadoc/com/jniwrapper/UInt64.html
http://publib.boulder.ibm.com/infocenter/rfthelp/v7r0m0/index.jsp?topic=/com.rational.test.ft.api.help/ApiReference/com/rational/test/value/UInt64.html
Operations with signed and unsigned integers are mostly identical, when using two's complement notation, which is what Java does. What this means is that if you have two 32-bit words a and b and want to compute their sum a+b, the same internal operation will produce the right answer regardless of whether you consider the words as being signed or unsigned. This will work properly for additions, subtractions, and multiplications.
The operations which must be sign-aware include:
Right shifts: a signed right shift duplicates the sign bit, while an unsigned right shift always inserts zeros. Java provides the ">>>" operator for unsigned right-shifting.
Divisions: an unsigned division is distinct from a signed division. When using 32-bit integers, you can convert the values to the 64-bit long type ("x & 0xFFFFFFFFL" does the "unsigned conversion" trick).
Comparisons: if you want to compare a with b as two 32-bit unsigned words, then you have two standard idioms:
if ((a + Integer.MIN_VALUE) < (b + Integer.MIN_VALUE)) { ... }
if ((a & 0xFFFFFFFFL) < (b & 0xFFFFFFFFL)) { ... }
Knowing that, the signed Java types are not a big hassle for cryptographic code. I have implemented many cryptographic primitives in Java, and the signed types are not an issue provided that you understand what you are writing. For instance, have a look at sphlib: this is an opensource library which implements many cryptographic hash functions, both in C and in Java. The Java code uses Java's signed types (int, long...) quite seamlessly, and it simply works.
Java does not have operator overloading, so Java-only "solutions" to get unsigned types will involve custom classes (such as the UInt64 class you link to), which will imply a massive performance penalty. You really do not want to do that.
Theoretically, one could define a Java-like language with unsigned types and implement a compiler which produces bytecode for the JVM (internally using the tricks I detail above for shifts, divisions and comparisons). I am not aware of any available tool which does that; and, as I said above, Java's signed types are just fine for cryptographic code (in other words, if you have trouble with such signed types, then I daresay that you do not know enough to implement cryptographic code securely, and you should refrain from doing so; instead, use existing opensource libraries).
This is a language feature, not a library feature, so there is no way to extend Java to support this functionality unless you change the language itself, in which case you'd need to make your own compiler.
However, if you need unsigned right-shifts, Java supports the >>> operator which works like the >> operator for unsigned types.
You can, however, make your own methods to perform arithmetic with signed types as though they were unsigned; this should work, for example:
static int multiplyUnsigned(int a, int b)
{
final bool highBitA = a < 0, highBitB = b < 0;
final long a2 = a & ~(1 << 31), b2 = b & ~(1 << 31);
final long result = (highBitA ? a2 | (1 << 31) : a2)
* (highBitB ? b2 | (1 << 31) : b2);
return (int)result;
}
Edit:
Thanks to #Ben's comment, we can simplify this:
static int multiplyUnsigned(int a, int b)
{
final long mask = (1L << 32) - 1;
return (int)((a & mask) * (b & mask));
}
Neither of these methods works, though, for the long type. You'd have to cast to a double, negate, multiply, and cast it back again in that case, which would likely kill any and all of your optimizations.