<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi everybody —<br class=""><div class=""><br class=""></div><div class="">I’d like to propose removing the “%” operator for floating-point types.</div><div class=""><br class=""></div><div class=""><b class="">Rationale:</b></div><div class="">While C and C++ do not provide the “%” operator for floating-point types, many newer languages do (Java, C#, and Python, to name just a few). &nbsp;Superficially this seems reasonable, but there are severe gotchas when % is applied to floating-point data, and the results are often extremely surprising to unwary users. &nbsp;C and C++ omitted this operator for good reason. &nbsp;Even if you think you want this operator, it is probably doing the wrong thing in subtle ways that will cause trouble for you in the future.</div><div class=""><br class=""></div><div class="">The % operator on integer types satisfies the division algorithm axiom: If b is non-zero and q = a/b, r = a%b, then a = q*b + r. &nbsp;This property does not hold for floating-point types, because a/b does not produce an integral value. &nbsp;If it did produce an integral value, it would need to be a bignum type of some sort (the integral part of DBL_MAX / DBL_MIN, for example, has over 2000 bits or 600 decimal digits).</div><div class=""><br class=""></div><div class="">Even if a bignum type were returned, or if we ignore the loss of the division algorithm axiom, % would still be deeply flawed. &nbsp;Whereas people are generally used to modest rounding errors in floating-point arithmetic, because % is not continuous small errors are frequently enormously magnified with catastrophic results:</div><div class=""><br class=""></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="font-family: Menlo; font-size: 11px;">(swift) 10.0 % 0.1</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 187, 199);">&nbsp; &nbsp; // r0 : Double = 0.0999999999999995 // What?!</div></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 187, 199);"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">[Explanation: 0.1 cannot be exactly represented in binary floating point; the actual value of “0.1” is&nbsp;0.1000000000000000055511151231257827021181583404541015625. &nbsp;Other than that rounding, the entire computation is exact.]</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><b class="">Proposed Approach:</b></div><div class="" style="margin: 0px; line-height: normal;">Remove the “%” operator for floating-point types. &nbsp;The operation is still be available via the C standard library fmod( ) function (which should be mapped to a Swiftier name, but that’s a separate proposal).</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><b class="">Alternative Considered:</b></div><div class="" style="margin: 0px; line-height: normal;">Instead of binding “%” to fmod( ), it could be bound to remainder( ), which implements the IEEE 754 remainder operation; this is just like fmod( ), except instead of returning the remainder under truncating division, it returns the remainder of round-to-nearest division, meaning that if a and b are positive, remainder(a,b) is in the range [-b/2, b/2] rather than [0, b). &nbsp;This still has a large discontinuity, but the discontinuity is moved away from zero, which makes it much less troublesome (that’s why IEEE 754 standardized this operation):</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="font-family: Menlo; font-size: 11px;">(swift) remainder(1, 0.1)</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 187, 199);">&nbsp; &nbsp; // r1 : Double = -0.000000000000000055511151231257827 // Looks like normal floating-point rounding</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 187, 199);"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">The downside to this alternative is that now % behaves totally differently for integer and floating-point data, and of course the division algorithm still doesn’t hold.</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><b class="">Proposal:</b></div><div class="" style="margin: 0px; line-height: normal;">Remove the % operator for floating-point types in Swift 3. &nbsp;Add a warning in Swift 2.2 that points out the replacement fmod(a, b).</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">Thanks for your feedback,</div><div class="" style="margin: 0px; line-height: normal;">– Steve</div></div></body></html>