2 days ago
On Fri, 28 Mar 2025 at 06:35, FeepingCreature via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Tuesday, 25 March 2025 at 04:44:15 UTC, Manu wrote:
> > I asked Grok to write me a portable 64x64->128 multiplication function in D to get the pattern, and this is what it wrote:
> >
> > What I loved is that its function returned a pair of ulong's, because apparently it made an assumption that we had in-language tuples! I wonder where it got that idea?
> >
> > We should learn from our AI overlords! :P
>
> Note: to get good results from AIs, ask them to write tests as well, then run the tests and post the answers and ask them to debug the issue. :) You have to handhold a bit.
>

I kinda feel like every commenter in this thread rather missed the point ;) I know how to multiply big numbers; I was just throwing random stuff at it trying to test its limits. The operation is not what I was interested in here; I just liked that it assumed we had tuples! It's right to do so as far as I'm concerned, and it's embarrassing that we don't.


2 days ago
On Sunday, 30 March 2025 at 09:25:56 UTC, Manu wrote:
> On Fri, 28 Mar 2025 at 02:16, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>> Cool! Now ask it to write an 80 bit IEEE floating point multiply!
>>
>> (So we can cross compile from Arm to X86!)
>
>
> I thought we had an arbitrary width float kicking around? I'm sure I've got one floating about somewhere...

Do you mean this: https://dlang.org/library/std/numeric/custom_float.html
2 days ago

On Tuesday, 25 March 2025 at 04:44:15 UTC, Manu wrote:

>

I asked Grok to write me a portable 64x64->128 multiplication function in D to get the pattern, and this is what it wrote:

I think it was aware of Int128 and Claude.ai replied as follows:

import std.int128;

auto mul64x64to128(ulong x, ulong y)
{
    uint x_low = cast(uint)x;
    uint x_high = cast(uint)(x >> 32);
    uint y_low = cast(uint)y;
    uint y_high = cast(uint)(y >> 32);

    ulong mul_ll = cast(ulong)x_low * y_low;
    ulong mul_lh = cast(ulong)x_low * y_high;
    ulong mul_hl = cast(ulong)x_high * y_low;
    ulong mul_hh = cast(ulong)x_high * y_high;

    ulong low = mul_ll;
    ulong high = mul_hh + (mul_hl >> 32) + (mul_lh >> 32);

    ulong mid = (mul_ll >> 32) + (mul_hl & 0xFFFFFFFF) + (mul_lh & 0xFFFFFFFF);
    low += (mid & 0xFFFFFFFF) << 32;
    high += mid >> 32;

    return Int128(high, low);
}

SDB@79

2 days ago
On Sunday, 30 March 2025 at 09:33:26 UTC, Manu wrote:
> On Fri, 28 Mar 2025 at 06:35, FeepingCreature via Digitalmars-d
>> Note: to get good results from AIs, ask them to write tests as well, then run the tests and post the answers and ask them to debug the issue. :) You have to handhold a bit.
>>
>
> I kinda feel like every commenter in this thread rather missed the point ;) I know how to multiply big numbers; I was just throwing random stuff at it trying to test its limits. The operation is not what I was interested in here; I just liked that it assumed we had tuples! It's right to do so as far as I'm concerned, and it's embarrassing that we don't.

To be clear, we should absolutely have tuples. :)
1 day ago
On Monday, 31 March 2025 at 05:50:13 UTC, FeepingCreature wrote:
>
> To be clear, we should absolutely have tuples. :)

Named tuples also, like in Typescript.
1 day ago
On Tuesday, 25 March 2025 at 04:44:15 UTC, Manu wrote:
> What I loved is that its function returned a pair of ulong's, because apparently it made an assumption that we had in-language tuples! I wonder where it got that idea?
>
> We should learn from our AI overlords! :P

Looks like Timon was working on his tuple implementation in February:
https://github.com/tgehr/dmd/commits/tuple-syntax/
Also:
https://dconf.org/2023/slides/gehr.pdf#page=109
1 day ago
On 3/30/2025 4:04 AM, Tim wrote:
> Do you mean this: https://dlang.org/library/std/numeric/custom_float.html

Not good enough:

"These formats are for storage only; all operations on them are performed by first implicitly extracting them to real first."
12 hours ago
On 3/31/25 22:37, Nick Treleaven wrote:
> On Tuesday, 25 March 2025 at 04:44:15 UTC, Manu wrote:
>> What I loved is that its function returned a pair of ulong's, because apparently it made an assumption that we had in-language tuples! I wonder where it got that idea?
>>
>> We should learn from our AI overlords! :P
> 
> Looks like Timon was working on his tuple implementation in February:
> https://github.com/tgehr/dmd/commits/tuple-syntax/
> Also:
> https://dconf.org/2023/slides/gehr.pdf#page=109

I was working a bit on unpacking, though I think it was mostly rebasing to master after that had undergone refactorings. It is more or less ready (and OpenD already pulled the current state), but there are various small things to finish.

E.g.:

- expanding a zero-element tuple does not work properly yet (in general, even unrelated to unpacking)
  https://github.com/dlang/dmd/issues/20842
  I though I would have time to maybe fix this, but got sidetracked last time I attempted to see it through.

- Unpacking does not yet support auto-expanding, for example:

  (AliasSeq!(int. int) x, int y) = tuple(1, 2, 3);

  does not work yet.

- I need to write an extensive test suite and address anything it may catch.

- I have to write the DIP and suffer through the bikeshedding on the forum.

Of course, one way to continue would be to just write tests for what works and pull this (e.g., behind a -preview switch) and to allow anyone who can spend the time required to take over the polishing effort. In general, I still fully intend to finish this, but I don't know when I will manage to get it over the finish line at the level of quality I think is perfect. It has already taken way too long, mostly because I have not been able to focus on this for any significant amount of time beside my day job and various other obligations.
6 hours ago
On 3/25/25 05:44, Manu wrote:
> I asked Grok to write me a portable 64x64->128 multiplication function in D to get the pattern, and this is what it wrote:
> 
> // Multiplies two 64-bit unsigned integers, returning a 128-bit result as (low, high)
> (ulong, ulong) mul64x64to128(ulong x, ulong y) {
>      // Split into 32-bit halves
>      uint x_l = cast(uint)x;
>      uint x_h = cast(uint)(x >> 32);
>      uint y_l = cast(uint)y;
>      uint y_h = cast(uint)(y >> 32);
> 
>      // Compute partial products
>      ulong p_ll = cast(ulong)x_l * y_l;        // Bits 0-63
>      ulong p_lh = cast(ulong)x_l * y_h;        // Bits 32-95
>      ulong p_hl = cast(ulong)x_h * y_l;        // Bits 32-95
>      ulong p_hh = cast(ulong)x_h * y_h;        // Bits 64-127
> 
>      ulong low = p_ll;                         // Lower 64 bits
>      uint p_lh_low = cast(uint)p_lh;
>      uint p_hl_low = cast(uint)p_hl;
>      uint p_ll_high = cast(uint)(p_ll >> 32);
> 
>      // Compute carry from middle terms
>      ulong sum_mid = cast(ulong)p_lh_low + p_hl_low + p_ll_high;
>      ulong carry = sum_mid >> 32;
> 
>      // Upper 64 bits
>      ulong high = p_hh + (p_lh >> 32) + (p_hl >> 32) + carry;
> 
>      return (low, high);
> }
> 
> 
> What I loved is that its function returned a pair of ulong's, because apparently it made an assumption that we had in-language tuples! I wonder where it got that idea?
> 
> We should learn from our AI overlords! :P

Well, it seems first they should learn how to multiply numbers (`low = p_ll` is wrong of course):

```
import std;

// Multiplies two 64-bit unsigned integers, returning a 128-bit result as (low, high)
(ulong, ulong) mul64x64to128(ulong x, ulong y) {
    // Split into 32-bit halves
    uint x_l = cast(uint)x;
    uint x_h = cast(uint)(x >> 32);
    uint y_l = cast(uint)y;
    uint y_h = cast(uint)(y >> 32);

    // Compute partial products
    ulong p_ll = cast(ulong)x_l * y_l;        // Bits 0-63
    ulong p_lh = cast(ulong)x_l * y_h;        // Bits 32-95
    ulong p_hl = cast(ulong)x_h * y_l;        // Bits 32-95
    ulong p_hh = cast(ulong)x_h * y_h;        // Bits 64-127

    ulong low = p_ll;                         // Lower 64 bits
    uint p_lh_low = cast(uint)p_lh;
    uint p_hl_low = cast(uint)p_hl;
    uint p_ll_high = cast(uint)(p_ll >> 32);

    // Compute carry from middle terms
    ulong sum_mid = cast(ulong)p_lh_low + p_hl_low + p_ll_high;
    ulong carry = sum_mid >> 32;

    // Upper 64 bits
    ulong high = p_hh + (p_lh >> 32) + (p_hl >> 32) + carry;

    return (low, high);
}

void main(){
    auto (low, high) = mul64x64to128(101010101010101010, 101010101010101010);
    assert((BigInt(high)<<64)+BigInt(low) == BigInt(101010101010101010)^^2);
}
```

```
$ ./dmd -run test_grok_tuple.d
core.exception.AssertError@test_grok_tuple.d(34): Assertion failure
----------------
??:? _d_assertp [0x62dc8b38d148]
??:? _Dmain [0x62dc8b382d9c]
```

(With my freshly rebased DMD fork at: https://github.com/tgehr/dmd/tree/52c336591aac0a2023a715ba92e95efc8da0f9ad )
1 2
Next ›   Last »