4

I tried this code on Dart: I get 28.5

void main() {
  double modulo = -1.5 % 30.0;
  print(modulo);
}

The same code in Javascript returns -1.5

let modulo =  -1.5 % 30;
console.log(modulo);

What is the equivalent of the javascript code above in Dart ?

ByteMe
  • 1,575
  • 1
  • 12
  • 23
TSR
  • 17,242
  • 27
  • 93
  • 197
  • Judt an idea: what happens of you add parenthesis, including all but the minus sign? My first guess would be that js does -(n%m) while dart does (-n)%m – Zsolt Szilagyi Aug 24 '20 at 23:43
  • 1
    It hasn't always been consistent even within the same language. "In C89 (and historical K&R implementations), the meaning of the remainder operator for negative operands was implementation-defined. This behavior was changed in C99, and the change remains in C11." https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152120 – shawnt00 Aug 24 '20 at 23:46
  • http://mathforum.org/library/drmath/view/52343.html – shawnt00 Aug 24 '20 at 23:48
  • 1
    in Python and in math `-1.5 % 30 = 28.5`. See [C and Python - different behaviour of the modulo (%) operation](https://stackoverflow.com/q/1907565/995714) – phuclv Aug 24 '20 at 23:51

2 Answers2

1

The documentation for num.operator % states (emphasis mine):

Returns the remainder of the Euclidean division. The Euclidean division of two integers a and b yields two integers q and r such that a == b * q + r and 0 <= r < b.abs().

...

The sign of the returned value r is always positive.

See remainder for the remainder of the truncating division.

Meanwhile, num.remainder says (again, emphasis mine):

The result r of this operation satisfies: this == (this ~/ other) * other + r. As a consequence the remainder r has the same sign as the divider this.

So if you use:

void main() {
  double modulo = (-1.5).remainder(30.0);
  print(modulo);
}

you'll get -1.5.

Note that both values are mathematically correct; there are two different answers that correspond to the two different ways that you can compute a negative quotient when performing integer division. You have a choice between rounding a negative quotient toward zero (also known as truncation) or toward negative infinity (flooring). remainder corresponds to a truncating division, and % corresponds to a flooring division.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
1

An issue was raised about this in the dart-lang repo a while ago. Apparently the % symbol in dart is an "Euclidean modulo operator rather than remainder."

An equivalent of what you are trying to do can be accomplished with

(-1.5).remainder(30.0)
ByteMe
  • 1,575
  • 1
  • 12
  • 23