On Sunday, 28 January 2024 at 17:25:49 UTC, mw wrote:
> See the result here:
https://forum.dlang.org/post/cagloplexjfzubncxuza@forum.dlang.org
I knew this outlandish output had to do with mixing of signed and unsigned types with resulting overflow. But I like the way Anthropic Claude2 explains it:
The outlandish output you're observing in the D code occurs due to an integer overflow. Let's break down what's happening:

Sum Calculation:
 The
sum(elem)
function correctly calculates the sum of all elements in the elem
array, which is 15 (1 + 2 + 3 + 4 + 5).
 So far, so good!

Average Calculation:
 Next, you calculate the average of the
a
array using the expression sum(a) / a.length
.
 The
sum(a)
part correctly computes the sum of the elements in a
, which is 5000 (since 5000 + 0 = 5000
).
 The issue arises with
a.length
.

Array Length and Unsigned Types:
 In D, the
.length
property of an array returns an unsigned integer (ulong
), which is an unsigned 64bit integer.
 The length of the
a
array is 2 (since it has two elements: 5000 and 0).

Integer Division:
 When you perform
sum(a) / a.length
, the division is done using integer division rules.
 The result of
5000 / 2
is 2500 (integer division truncates the decimal part).

Overflow:
 The result of
2500
is stored in the c
variable, which is of type ulong
.
 Since
ulong
is an unsigned type, the value wraps around due to overflow.
 The actual value stored in
c
is 9223372036854773308, which is the result of wrapping around from 2500 to a large positive value.

Explanation:
 The overflow occurs because
2500
(as a signed integer) is equivalent to a large positive value when interpreted as an unsigned 64bit integer.
 The result is not what you intended for the average calculation.
To fix this, you can explicitly cast the sum to a signed integer before dividing to ensure correct behavior:
auto c = cast(double)(sum(a)) / a.length;
This will correctly compute the average and prevent overflow. The output should now match your expectations! ðŸš€
The corrected code:
module array_length_forum;
import std.algorithm;
import std.stdio;
void main() {
auto elem = [1, 2, 3, 4, 5];
writeln(sum(elem)); // 15 < // The sum of all the elements in the range
long[]a = [5000, 0];
//auto c = sum(a)/a.length; // length() returns 'ulong', inferred as 'ulong'
auto c = cast(double)(sum(a)) / a.length;
writeln(typeid(c)); // double
writeln(c); // 2500 correct output
}