<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Dec 18, 2015, at 1:12 PM, Stephen Canon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<div><blockquote type="cite" class=""><div class=""><div 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></div></blockquote><div><br class=""></div><div>I support removing this - it is actively harmful for a surprising operation like this to have such short and inviting syntax. &nbsp;As asked downthread, have you given any thought into whether a Decimal type would support this operation? &nbsp;</div><div><br class=""></div><div>-Chris</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><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>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=RC5Cq0zAxCHc1sM9Uy3-2BojrrUAw-2F96zH69NULNHPvCvLQDtTDVB6LegroDTeCLIWKasVctOfsZZxQm7pAYxQFmkz-2BMtIwzkdtsc6eoVxdNbcViJcQdflWJDd8UnruHhtmFhOrE1Y2-2B4oUBUFQGZ7fI1eZ3d6N1RDUZu-2BzajRjSWl5pFUPPIj5R-2FOG-2Fz-2BXA-2B-2FfQeIHvawGvh445f4Rt5fHFBb7TbkZZGAvXkMR5HbRFY-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>