maybe a floating point issue?

Timon Gehr timon.gehr at gmx.ch
Fri Sep 19 19:07:44 UTC 2025


On 9/19/25 08:23, czylabsonasa wrote:
> Hi.
> 
> I'm trying to solve a programming contest [problem](https:// 
> open.kattis.com/problems/anthony) in D. The almost identical solution in 
> C++ got accepted, but I'm unable to find the issue in the D code... 
> Maybe some D expert catch some trivial error in my code?
> Here is the D source:
> 
> ```d
> // Anthony_and_Cora_anthony
> 
> import std;
> 
> alias i32=int;
> alias i64=long;
> alias f64=double;
> alias f128=real;
> alias fT=f64;
> 
> void main(){
>     i32 A,C; readf("%d %d\n",A,C);
>     auto p=new fT[](A+C);
>     for(i32 i=1;i<=A+C-1;i++){
>        readf("%f\n",p[i]);
>     }
>     auto win=new fT[][](A+1,C+1);
>     for(i32 i=0;i<=A;i++){
>        for(i32 j=0;j<=C;j++){
>           win[i][j]=-1.0;
>        }
>     }
>     for(i32 i=1;i<=A;i++){
>        win[i][0]=1.0;
>     }
>     for(i32 j=0;j<=C;j++){ // j=0 ?
>        win[0][j]=0.0;
>     }
> 
>     void Trav(i32 a,i32 c,i32 k){
>        if(win[a][c]<-0.5){
>           Trav(a-1,c,k+1);
>           Trav(a,c-1,k+1);
>           win[a][c]=p[k]*win[a][c-1]+(1-p[k])*win[a-1][c];
>        }
>     }
> 
>     Trav(A,C,1);
>     writef("%.7f\n",win[A][C]);
> }
> ```
> 
> The approach is a top-down one with memoization. Tried both double and 
> real, with no success. What is "surprising" the following C++ code is 
> accepted by the judge system:
> 
> ```c++
> // Anthony_and_Cora_anthony
> #include <bits/stdc++.h>
> using namespace std;
> 
> using i32=int;
> using f64=double;
> using f128=long double;
> using fT=f64;
> 
> vector<vector<fT>> win;
> vector<fT> p;
> void Trav(i32 a,i32 c,i32 k){
>     if(win[a][c]<-0.5){
>        Trav(a-1,c,k+1);
>        Trav(a,c-1,k+1);
>        win[a][c]=p[k]*win[a][c-1]+(1-p[k])*win[a-1][c];
>     }
> }
> 
> int main(){
>     i32 A,C; cin>>A>>C;
>     p.resize(A+C+1);
>     for(i32 i=1;i<=A+C-1;i++){
>        cin>>p[i];
>     }
>     win.resize(A+1);
>     for(i32 i=0;i<=A;i++){
>        win[i].resize(C+1);
>     }
>     for(i32 i=0;i<=A;i++){
>        for(i32 j=0;j<=C;j++){
>           win[i][j]=-1.0;
>        }
>     }
>     for(i32 i=1;i<=A;i++){
>        win[i][0]=1.0;
>     }
>     for(i32 j=0;j<=C;j++){
>        win[0][j]=0.0;
>     }
> 
>     Trav(A,C,1);
>     cout<<setprecision(7)<<fixed<<win[A][C]<<'\n';
> }
> 
> ```
> 
> The D code was tested against the C++ code w/ randomly generated cases, 
> using dmd,ldc2 and gdc-12 compilers, but even `diff` did not give any 
> difference...
> 
> cheers.
> 
> 


FWIW: if we improve the ability of the optimizer to do alias analysis, 
it passes:


```d
import std;

alias i32=int;
alias i64=long;
alias f64=double;
alias f128=real;
alias fT=f64;

void main(){
    i32 A,C; readf("%d %d\n",A,C);

    auto p=new fT[](A+C);
    for(i32 i=1;i<=A+C-1;i++){
       readf("%f\n",p[i]);
    }

    const i32 stride=C+1;
    auto win=new fT[]((A+1)*(C+1));

    for(i32 i=0;i<=A;i++){
       for(i32 j=0;j<=C;j++){
          win[i*stride+j]=-1.0;
       }
    }
    for(i32 i=1;i<=A;i++){
       win[i*stride+0]=1.0;
    }
    for(i32 j=0;j<=C;j++){
       win[0*stride+j]=0.0;
    }

    void Trav(i32 a,i32 c,i32 k){<
       const idx=a*stride+c;
       if(win[idx]<-0.5){
          Trav(a-1,c,k+1);
          Trav(a,c-1,k+1);
          win[idx]=p[k]*win[a*stride+(c-1)]+(1-p[k])*win[(a-1)*stride+c];
       }
    }

    Trav(A,C,1);
    writef("%.7f\n",win[A*stride+C]);
}
```

Not sure why this happens with GDC on -O2, I think LDC would refrain 
from changing results by default.


More information about the Digitalmars-d mailing list