August 12, 2020 [phobos] std.numeric returns incorrect results for integer types. | ||||
---|---|---|---|---|
| ||||
std.numeric is listed in the documentation as "Floating point numerics functions.". I have noted that the noramlize function for std.numeric will accept an integer type, and report a dud result. ulong[] arr = [540,640,44]; normalize!(typeof(arr))(arr,256); \\ arr = [0, 0, 0] One would expect either an error, or a valid result here. I think this is a design flaw, as the function happy returns 0 without complaint. This would lead to incorrect behaviour for someone who missed the scant mention that its for floats. I think that there should be either a template constraint to reject integral types, or that it should handle integral types correctly. I have found the below version handles integer types correctly, *IF* that is the path you want to take. I can make a pull request if necessary. bool normalize(R)(R range, ElementType!(R) sum = 1) if (isForwardRange!(R)) { ElementType!(R) s = 0; // Step 1: Compute sum and length of the range static if (hasLength!(R)) { const length = range.length; foreach (e; range) { s += e; } } else { uint length = 0; foreach (e; range) { s += e; ++length; } } // Step 2: perform normalization if (s == 0) { if (length) { immutable f = sum / range.length; foreach (ref e; range) e = f; } return false; } // The path most traveled assert(s >= 0); static if (isIntegral!(ElementType!(R))) { immutable f = sum / s.to!real; foreach (ref e; range) e = round(e*f).to!(ElementType!(R)); } else { immutable f = sum / s; foreach (ref e; range) e *= f; } return true; } _______________________________________________ phobos mailing list phobos@puremagic.com http://lists.puremagic.com/mailman/listinfo/phobos |
Copyright © 1999-2021 by the D Language Foundation