Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / September 2007

Tip: Looking for answers? Try searching our database.

Using Remainder Operator with Negative Divident

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
valentin tihomirov - 23 Sep 2007 22:22 GMT
My rateonale is:
   -1 mod 3 = must be 3
   0 mod 3  = 0
   1 mod 3  = 1
   2 mod 3  = 2
   3 mod 3  = 3
   4 mod 3  = 0
                   = 1
                   = 2
                   = 3
                   = 0

We note a sequence: 0 1 2 3 0 1 2 3 0 1 2 3. Going in backward direction, we
get 3 2 1 0 3 2 1 0 3 2 1 0.

Since (0 % N) is 0, going one step back (-1 % N) must result in N. But c#
compiler gives me -1. It is wrong. Fix it. The C#LS seems wrong. Correct it.
Jon Skeet [C# MVP] - 23 Sep 2007 22:53 GMT
> My rateonale is:
>     -1 mod 3 = must be 3
[quoted text clipped - 13 lines]
> Since (0 % N) is 0, going one step back (-1 % N) must result in N. But c#
> compiler gives me -1. It is wrong. Fix it. The C#LS seems wrong. Correct it.

Your understanding of "remainder" is too rigid. Fix it :)

Seriously, there are different understandings of how remainders should
work with negative numbers. Some systems use the sign of the dividend,
others use the sign of the divisor. See
http://en.wikipedia.org/wiki/Modulo_operation for a list.

You know what I think is *really* broken? To leave it to the
implementation - which is what C++ did, at least at the time of
Stroustrup's 2nd edition. (I seriously hope it's been fixed since
then.)

(I have in my head that "remainder" should work as shown in C#, but if
a language defines a "modulo" operator, that should always be non-
negative. However, I can't find any evidence backing that up.)

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Doug Semler - 23 Sep 2007 23:15 GMT
> (I have in my head that "remainder" should work as shown in C#, but if
> a language defines a "modulo" operator, that should always be non-
> negative. However, I can't find any evidence backing that up.)

What should be non-negative?  The result of the modulus operator?  If the
dividend is negative in C#, the result of the modulus is negative, which
actually makes sense mathematically (what would you need to ADD to the
result of the divisor times the result of the division to get back to your
dividend?)  Note this is only for integer modulus.  I always hated float
modulus :)

-3 / -2 = 1  - what would you need to add? (-1) so -3 % -2 = -1
-3 / 2 = -1 - what do you add? -1 again.  so -3 % 2 = -1
3 / -2 = -1  - what do you need to add to -1 * -2?

Signature

Doug Semler, MCPD
a.a. #705, BAAWA.  EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?

Doug Semler - 23 Sep 2007 23:22 GMT
>> (I have in my head that "remainder" should work as shown in C#, but if
>> a language defines a "modulo" operator, that should always be non-
[quoted text clipped - 6 lines]
> dividend?)  Note this is only for integer modulus.  I always hated float
> modulus :)

Note that my note above was for the example below, not that float modulus
acted differently with respect to sign <g>

> -3 / -2 = 1  - what would you need to add? (-1) so -3 % -2 = -1
> -3 / 2 = -1 - what do you add? -1 again.  so -3 % 2 = -1
> 3 / -2 = -1  - what do you need to add to -1 * -2?

Signature

Doug Semler, MCPD
a.a. #705, BAAWA.  EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?

Jon Skeet [C# MVP] - 24 Sep 2007 00:08 GMT
> > (I have in my head that "remainder" should work as shown in C#, but if
> > a language defines a "modulo" operator, that should always be non-
> > negative. However, I can't find any evidence backing that up.)
>
> What should be non-negative?  The result of the modulus operator?

Yes - in my head, anyway :)

> If the dividend is negative in C#, the result of the modulus is negative, which
> actually makes sense mathematically (what would you need to ADD to the
> result of the divisor times the result of the division to get back to your
> dividend?)  Note this is only for integer modulus.  I always hated float
> modulus :)

Yes, I totally see your point. Of course, it depends on how you round
the division aspect. If you define integer division to round down, i.e.
to always return the largest number d such that d*x < y, then you will
always have a non-negative integer r such that d*x+r = y. However, C#
(and many other computer languages) use round-towards-zero for
division, which is where the negative remainder comes in.

At least, that's what I currently think - but I'm about to go to bed,
so anything I write now probably shouldn't be trusted.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

valentin tihomirov - 24 Sep 2007 08:24 GMT
> Your understanding of "remainder" is too rigid. Fix it :)

:) You do not understand. THIS IS REQUIREMENT OF MY PROGRAM!

This math is required for Rayal Mail
http://emce.gov.uk/documents/publications/royal_mail/4)%20Royal%20Mail%20Cleanma
il%20Brochure.pdf

checksum character computation. They map chars (0 1 2 3 4 5 ...) to
increments (1 2 3 4 5 0) by (i + 1) % 6. Afterwards, the sum is divided by 6
and the index (0 1 2 3 4 5 ...) must be reporduced from the reminder (1 2 3
4 5 0 ...). In order for the math to work, the reverse operation (sum - 1) %
6 must treat the last column 0 as 6 resulting in char 5.
Jon Skeet [C# MVP] - 24 Sep 2007 08:37 GMT
> > Your understanding of "remainder" is too rigid. Fix it :)
>
> :) You do not understand. THIS IS REQUIREMENT OF MY PROGRAM!

So write a method to behave how you want it to, rather than trying to
force the rest of us to change.

The following probably isn't the cleanest way of doing it, but it's
incredibly simple (assuming a positive divisor - when the divisor is
negative, I don't know what you'd want to do).

public static int Modulus (int dividend, int divisor)
{
   int remainder = dividend % divisor;
   return remainder >= 0 ? remainder : remainder+divisor;
}

> This math is required for Rayal Mail
> http://emce.gov.uk/documents/publications/royal_mail/4)%20Royal%20Mai...
[quoted text clipped - 3 lines]
> 4 5 0 ...). In order for the math to work, the reverse operation (sum - 1) %
> 6 must treat the last column 0 as 6 resulting in char 5.

So you expect a language to change to support a single use case which
doesn't seem terribly well thought out? I'm afraid I have very little
sympathy for that position. Work round it - it's trivial to do so.

Jon
valentin tihomirov - 24 Sep 2007 09:27 GMT
>> > Your understanding of "remainder" is too rigid. Fix it :)
>>
[quoted text clipped - 29 lines]
>
> Jon

Actually, I have determined that their algorithm can be implemented without
wrapping the last column to 0 forth and back, which require these ugly
if-else. It is the Royal Mail User Guide, which must be fixed then
(simplified).
Jon Skeet [C# MVP] - 24 Sep 2007 10:01 GMT
> Actually, I have determined that their algorithm can be implemented without
> wrapping the last column to 0 forth and back, which require these ugly
> if-else. It is the Royal Mail User Guide, which must be fixed then
> (simplified).

I'd prefer their algorithm to be fixed - keep the content of the table
where it is, but make 0 the first row/column. Too late to do that now,
but clearly you can remap the table if you're willing to change where
the contents are. It's only a lookup, after all.

Jon
valentin tihomirov - 24 Sep 2007 10:21 GMT
> I'd prefer their algorithm to be fixed - keep the content of the table
> where it is, but make 0 the first row/column. Too late to do that now,
> but clearly you can remap the table if you're willing to change where
> the contents are. It's only a lookup, after all.

The algorithm seems correctly designed. The explanation is bad moving the 0
column into the end and back for no reason.
Jon Skeet [C# MVP] - 24 Sep 2007 10:23 GMT
> > I'd prefer their algorithm to be fixed - keep the content of the table
> > where it is, but make 0 the first row/column. Too late to do that now,
[quoted text clipped - 3 lines]
> The algorithm seems correctly designed. The explanation is bad moving the 0
> column into the end and back for no reason.

Yes, by "algorithm" I guess I really meant "data used by the
algorithm" - i.e. the table.

Either way, it's certainly not C#'s fault :)

Jon
james.curran@gmail.com - 24 Sep 2007 16:11 GMT
> You know what I think is *really* broken? To leave it to the
> implementation - which is what C++ did, at least at the time of
> Stroustrup's 2nd edition. (I seriously hope it's been fixed since
> then.)

I doubt it. Especially considering the C++ standard still does not
require a particular binary representation for -1, or, for that
matter, a particular value for 32767+1.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.