Sep 26, 2014 at 9:50 PM
Edited Sep 26, 2014 at 10:10 PM

It's division, but it will always evaluate an integer result:
int i0 = 5 / 2; // Operands are integers, evaluates integer 2.
int i1 = 5.0 / 2.0; // Operands are doubles, evaluates double 2.5  Error on assignment
int i2 = 5.0 ~/ 2.0; // Operands are doubles, evaluates integer 2  No error
It's essentially syntactic sugar for:
int i2 = (int)(5.0 / 2.0);
It could literally just be converted into an (int) cast by the compiler (like above) as opposed to being a 'proper' operator  which should not be too deep of a change.
The assignment operator version would be ~/=
a ~/= b;
I came across this operator in the Dart programming language and thought it would be a very handy addition.
The Dart operator reference can be found
here, although there is no explicit explanation of the ~/ operator.




If this is considered, it would be logical to use the \ operator. This has been used in Visual Basic for many years for integer divide.
Rules deserve attention as C# programmers are often surprised that C# truncates on the implicit integer divide (not round).
7/4 == 1



Sep 28, 2014 at 3:58 PM
Edited Sep 28, 2014 at 3:59 PM

I'm surprised there is a special operator in Dart for this. At least for me, much more common is that you divide two integers and require a double, i.e.
(double)5 / 2 .




christoph_hausner wrote:
I'm surprised there is a special operator in Dart for this. At least for me, much more common is that you divide two integers and require a double, i.e.
(double)5 / 2 .
The various kinds of wholenumber and integer division should be considered fundamentally different operations from realnumber division; I consider it unfortunate that the creators of FORTRAN decided to notate wholenumber division using
/ rather than .DIV. and other languages like C followed its lead. Although code which divides two floatingpoint numbers will often want a floatingpoint result, and code which divides two integers will often want an integer result,
neither statement is true 100% of the time. Use of separate operators would have allowed code to ask for whatever kind of division it actually wanted in each particular case.




This would be unnecessary with C#. The Cheritage of languages differentiates between division operations based on the types of the operands. Dart (and VB) don't differentiate, they always force that
/ perform a floating point division regardless of the operands and require that the programmer optin to integral division through a separate operator. If you want to optin to integer division in C# you just need to ensure that both operands are
integers.
Dart probably inherited this from JavaScript which only has floating point types.




Halo_Four wrote:
This would be unnecessary with C#. The Cheritage of languages differentiates between division operations based on the types of the operands.
C# presently has truncating discrete division operators for integertype operands; it does not have any other form of discrete division operators, though others are often more useful. Having operators for floored and rounded discrete division with either integer
or floatingpoint operands, along with matching remainder operators, could be nice, though for such division operators to be most useful they should allow their result to be implicitly converted to either
Int32 or Int64 .
If e.g. ~/ were defined as "rounding discrete division" and
~% were defined as the corresponding remainder, that would allow code like
n >= 0 ? (n+1)/3 : (n1)/3 to be replaced with n ~/ 3 .




supercat wrote:
Halo_Four wrote:
This would be unnecessary with C#. The Cheritage of languages differentiates between division operations based on the types of the operands.
C# presently has truncating discrete division operators for integertype operands; it does not have any other form of discrete division operators, though others are often more useful. Having operators for floored and rounded discrete division with either integer
or floatingpoint operands, along with matching remainder operators, could be nice, though for such division operators to be most useful they should allow their result to be implicitly converted to either
Int32 or Int64 .
If e.g. ~/ were defined as "rounding discrete division" and
~% were defined as the corresponding remainder, that would allow code like
n >= 0 ? (n+1)/3 : (n1)/3 to be replaced with n ~/ 3 .
That is the definition of integer division, and how it is implemented not just in IL but also on all x86 CPUs, if not all CPUs. If you want any other form of rounding you have to cast the values to floating point, divide and then round. With that comes with
massive performance penalty of doing so, approximately a full order of magnitude. If that's the behavior you want you're free to use it exactly like VB does it, by casting to
System.Double and calling Math.Round .
Dim x As Integer = 10
Dim y As Integer = 3
Dim result As Integer = x / y;
is the same as:
int x = 10;
int y = 3;
int result = (int)(Math.Round((double)x / y, MidpointRounding.ToEven);



Sep 30, 2014 at 4:52 PM
Edited Sep 30, 2014 at 4:54 PM

Although the IDIV instruction performs truncated integer division, it is seldom the most efficient way to divide by a constant. In most cases, floored division by a constant and its associated modulus would be faster than truncated division and the associated
remainder. For example, floored division by 4 can be performed via asr ax,2 . Halvesroundup division by four could be performed by
asr ax,2 / adc ax,0 . Either floored division or halvesroundup division by a nonpoweroftwo constant may be performed via
mov ax,const1 / mul src / add ax,const2 / adc dx,const3 . In every case I can think of (other than division by one) the instruction sequence is shorter and faster than what would be required for truncating division, even if truncated division didn't
necessitate the use of additional user code to adjust the result to match user code requirements.




supercat wrote:
Although the IDIV instruction performs truncated integer division, it is seldom the most efficient way to divide by a constant.
Of course, and the JIT knows this and will use better sequences of op codes when it has enough information to do so where it is functionality identical to IDIV.
To add new forms of division you'd have to add new corresponding IL op codes (or prefixes), otherwise you'd be stuck with what I mentioned above.




Halo_Four wrote:
Of course, and the JIT knows this and will use better sequences of op codes when it has enough information to do so where it is functionality identical to IDIV.
To add new forms of division you'd have to add new corresponding IL op codes (or prefixes), otherwise you'd be stuck with what I mentioned above.
When dividing by a constant, I would expect floored or roundhalfup division could often be computed more efficiently than truncated division, even if the C# compiler had to generate IL to perform it. For example, suppose you want to define a method to divide
by X by a constant SCALE, rounded to the nearest integer, and you don't care which way which way halves get rounded. If SCALE was a known power of two (e.g. eight) and X was known not to be particularly close to the maximum possible integer value, one could
simply compute (X+4)>>3 . Can you suggest any clean way of writing the code such that it would be no less efficient if SCALE happens to be a power of two, but would yield correct results even if SCALE were some other value?




supercat wrote:
Halo_Four wrote:
Of course, and the JIT knows this and will use better sequences of op codes when it has enough information to do so where it is functionality identical to IDIV.
To add new forms of division you'd have to add new corresponding IL op codes (or prefixes), otherwise you'd be stuck with what I mentioned above.
When dividing by a constant, I would expect floored or roundhalfup division could often be computed more efficiently than truncated division, even if the C# compiler had to generate IL to perform it. For example, suppose you want to define a method to divide
by X by a constant SCALE, rounded to the nearest integer, and you don't care which way which way halves get rounded. If SCALE was a known power of two (e.g. eight) and X was known not to be particularly close to the maximum possible integer value, one could
simply compute (X+4)>>3 . Can you suggest any clean way of writing the code such that it would be no less efficient if SCALE happens to be a power of two, but would yield correct results even if SCALE were some other value?
The efficiency is not as important as the intent. Integer division is expected to behave in one manner so only one IL opcode was dedicated to it. The JIT certainly shouldn't be left to decide that another method might be faster if the outcome would not be the
same. And IL shouldn't represent what would be a platformspecific optimization, only the intent. Even in the case of division operations that could be replaced by bit shifting the C# compiler emits a
div opcode and allows the JIT to figure out that the divisor is a constant containing a power of two, which it is quite capable of doing. If there were to be alternate methods of accomplishing integer division which would result in differentthanstandard
results for integer division then that would warrant the addition of new IL opcodes to represent the intent with deterministic results.




Halo_Four wrote:
supercat wrote:
Can you suggest any clean way of writing the code such that it would be no less efficient if SCALE happens to be a power of two, but would yield correct results even if SCALE were some other value?
The efficiency is not as important as the intent. Integer division is expected to behave in one manner so only one IL opcode was dedicated to it. The JIT certainly shouldn't be left to decide that another method might be faster if the outcome would not be the
same.
It is not uncommon for a program to need to divide two numbers in such fashion as to produce a rounded quotient. If code needs to compute the rounded value of x/SCALE, can you offer any way of writing that which would, if SCALE happened to equal 8, be no slower
than ((x>>2)+1)>>1 , but which would work for any constant value of SCALE? My
intent is to divide by SCALE, with rounding, efficiently. A roundeddiscretedivision operator would make it possible to express that intention clearly. What clear means of expression would you suggest in the absence of an operator?




supercat wrote:
Halo_Four wrote:
supercat wrote:
Can you suggest any clean way of writing the code such that it would be no less efficient if SCALE happens to be a power of two, but would yield correct results even if SCALE were some other value?
The efficiency is not as important as the intent. Integer division is expected to behave in one manner so only one IL opcode was dedicated to it. The JIT certainly shouldn't be left to decide that another method might be faster if the outcome would not be the
same.
It is not uncommon for a program to need to divide two numbers in such fashion as to produce a rounded quotient. If code needs to compute the rounded value of x/SCALE, can you offer any way of writing that which would, if SCALE happened to equal 8, be no slower
than ((x>>2)+1)>>1 , but which would work for any constant value of SCALE? My
intent is to divide by SCALE, with rounding, efficiently. A roundeddiscretedivision operator would make it possible to express that intention clearly. What clear means of expression would you suggest in the absence of an operator?
I would suggest that your operator requires a corresponding opcode to express your clear intent to the JIT.




Halo_Four wrote:
I would suggest that your operator requires a corresponding opcode to express your clear intent to the JIT.
Why would a special opcode be required? Why could not the compiler simply generate some CIL to perform the requested computation? If the dividend isn't a constant the code might be a little clunky,
but it would probably be no worse than what a programmer who wanted truncated or rounded division would have to write anyway.

