Task: Pathological floating point problems

C: #include<stdio.h>
#include<gmp.h>

void firstCase(){
	mpf_t a,b,c;
	
	mpf_inits(a,b,c,NULL);
	
	mpf_set_str(a,"0.1",10);
	mpf_set_str(b,"0.2",10);
	mpf_add(c,a,b);
	
	gmp_printf("\n0.1 + 0.2 = %.*Ff",20,c);
}

void pathologicalSeries(){
	int n;
	mpf_t v1, v2, vn, a1, a2, a3, t2, t3, prod;
	
	mpf_inits(v1,v2,vn, a1, a2, a3, t2, t3, prod,NULL);
	
	mpf_set_str(v1,"2",10);
	mpf_set_str(v2,"-4",10);
	mpf_set_str(a1,"111",10);
	mpf_set_str(a2,"1130",10);
	mpf_set_str(a3,"3000",10);
	
	for(n=3;n<=100;n++){
		mpf_div(t2,a2,v2);
		mpf_mul(prod,v1,v2);
		mpf_div(t3,a3,prod);
		mpf_add(vn,a1,t3);
		mpf_sub(vn,vn,t2);
		
		if((n>=3&&n<=8) || n==20 || n==30 || n==50 || n==100){
			gmp_printf("\nv_%d : %.*Ff",n,(n==3)?1:(n>=4&&n<=7)?6:(n==8)?7:(n==20)?16:(n==30)?24:(n==50)?40:78,vn);
		}
		
		mpf_set(v1,v2);
		mpf_set(v2,vn);
	}
}

void healthySeries(){
	int n;
	
	mpf_t num,denom,result;
	mpq_t v1, v2, vn, a1, a2, a3, t2, t3, prod;
	
	mpf_inits(num,denom,result,NULL);
	mpq_inits(v1,v2,vn, a1, a2, a3, t2, t3, prod,NULL);
	
	mpq_set_str(v1,"2",10);
	mpq_set_str(v2,"-4",10);
	mpq_set_str(a1,"111",10);
	mpq_set_str(a2,"1130",10);
	mpq_set_str(a3,"3000",10);
	
	for(n=3;n<=100;n++){
		mpq_div(t2,a2,v2);
		mpq_mul(prod,v1,v2);
		mpq_div(t3,a3,prod);
		mpq_add(vn,a1,t3);
		mpq_sub(vn,vn,t2);
		
		if((n>=3&&n<=8) || n==20 || n==30 || n==50 || n==100){
			mpf_set_z(num,mpq_numref(vn));
			mpf_set_z(denom,mpq_denref(vn));
			mpf_div(result,num,denom);

			gmp_printf("\nv_%d : %.*Ff",n,(n==3)?1:(n>=4&&n<=7)?6:(n==8)?7:(n==20)?16:(n==30)?24:(n==50)?40:78,result);
		}
		
		mpq_set(v1,v2);
		mpq_set(v2,vn);
	}
}

int main()
{	
	mpz_t rangeProd;
	
	firstCase();
	
	printf("\n\nPathological Series : ");
	
	pathologicalSeries();
	
	printf("\n\nNow a bit healthier : ");
	
	healthySeries();

	return 0;
}




Go: package main

import (
    "fmt"
    "math/big"
)

func main() {
    sequence()
    bank()
    rump()
}

func sequence() {
    
    var v, v1 big.Rat
    v1.SetInt64(2)
    v.SetInt64(-4)
    n := 2
    c111 := big.NewRat(111, 1)
    c1130 := big.NewRat(1130, 1)
    c3000 := big.NewRat(3000, 1)
    var t2, t3 big.Rat
    r := func() (vn big.Rat) {
        vn.Add(vn.Sub(c111, t2.Quo(c1130, &v)), t3.Quo(c3000, t3.Mul(&v, &v1)))
        return
    }
    fmt.Println("  n  sequence value")
    for _, x := range []int{3, 4, 5, 6, 7, 8, 20, 30, 50, 100} {
        for ; n < x; n++ {
            v1, v = v, r()
        }
        f, _ := v.Float64()
        fmt.Printf("%3d %19.16f\n", n, f)
    }
}

func bank() {
    
    var balance struct{ e, d big.Int }
    
    balance.e.SetInt64(1)
    balance.d.SetInt64(-1)
    
    var m, one big.Int
    one.SetInt64(1)
    for y := 1; y <= 25; y++ {
        m.SetInt64(int64(y))
        balance.e.Mul(&m, &balance.e)
        balance.d.Mul(&m, &balance.d)
        balance.d.Sub(&balance.d, &one)
    }
    
    var e, ef, df, b big.Float
    e.SetPrec(100).SetString("2.71828182845904523536028747135")
    ef.SetInt(&balance.e)
    df.SetInt(&balance.d)
    b.Add(b.Mul(&e, &ef), &df)
    fmt.Printf("Bank balance after 25 years: $%.2f\n", &b)
}

func rump() {
    a, b := 77617., 33096.
    fmt.Printf("Rump f(%g, %g): %g\n", a, b, f(a, b))
}

func f(a, b float64) float64 {
    
    
    fp := func(x float64) *big.Float { return big.NewFloat(x).SetPrec(128) }
    a1 := fp(a)
    b1 := fp(b)
    a2 := new(big.Float).Mul(a1, a1)
    b2 := new(big.Float).Mul(b1, b1)
    b4 := new(big.Float).Mul(b2, b2)
    b6 := new(big.Float).Mul(b2, b4)
    b8 := new(big.Float).Mul(b4, b4)
    two := fp(2)
    t1 := fp(333.75)
    t1.Mul(t1, b6)
    t21 := fp(11)
    t21.Mul(t21.Mul(t21, a2), b2)
    t23 := fp(121)
    t23.Mul(t23, b4)
    t2 := new(big.Float).Sub(t21, b6)
    t2.Mul(a2, t2.Sub(t2.Sub(t2, t23), two))
    t3 := fp(5.5)
    t3.Mul(t3, b8)
    t4 := new(big.Float).Mul(two, b1)
    t4.Quo(a1, t4)
    s := new(big.Float).Add(t1, t2)
    f64, _ := s.Add(s.Add(s, t3), t4).Float64()
    return f64
}