Task: Numeric error propagation

C: #include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
 
typedef struct{
    double value;
    double delta;
}imprecise;
 
#define SQR(x) ((x) * (x))
imprecise imprecise_add(imprecise a, imprecise b)
{
    imprecise ret;
    ret.value = a.value + b.value;
    ret.delta = sqrt(SQR(a.delta) + SQR(b.delta));
    return ret;
}
 
imprecise imprecise_mul(imprecise a, imprecise b)
{
    imprecise ret;
    ret.value = a.value * b.value;
    ret.delta = sqrt(SQR(a.value * b.delta) + SQR(b.value * a.delta));
    return ret;
}
 
imprecise imprecise_div(imprecise a, imprecise b)
{
    imprecise ret;
    ret.value = a.value / b.value;
    ret.delta = sqrt(SQR(a.value * b.delta) + SQR(b.value * a.delta)) / SQR(b.value);
    return ret;
}
 
imprecise imprecise_pow(imprecise a, double c)
{
    imprecise ret;
    ret.value = pow(a.value, c);
    ret.delta = fabs(ret.value * c * a.delta / a.value);
    return ret;
}

char* printImprecise(imprecise val)
{
	char principal[30],error[30],*string,sign[2];
	sign[0] = 241;    
	sign[1] = 00;
	
	sprintf(principal,"%f",val.value);
	sprintf(error,"%f",val.delta);
	
	string = (char*)malloc((strlen(principal)+1+strlen(error)+1)*sizeof(char));
	
	strcpy(string,principal);
	strcat(string,sign);
	strcat(string,error);
	
	return string;
}
 
int main(void) {
    imprecise x1 = {100, 1.1};
    imprecise y1 = {50, 1.2};
    imprecise x2 = {-200, 2.2};
    imprecise y2 = {-100, 2.3};
    imprecise d;
 
    d = imprecise_pow(imprecise_add(imprecise_pow(imprecise_add(x1, x2), 2),imprecise_pow(imprecise_add(y1, y2), 2)), 0.5);
    printf("Distance, d, between the following points :");
    printf("\n( x1, y1) = ( %s, %s)",printImprecise(x1),printImprecise(y1));
    printf("\n( x2, y2) = ( %s, %s)",printImprecise(x2),printImprecise(y2));
    printf("\nis d = %s", printImprecise(d));
    return 0;
}




Go: package main

import (
    "fmt"
    "math"
)




type unc struct {
    n float64 
    s float64 
}


func newUnc(n, s float64) *unc {
    return &unc{n, s * s}
}



func (z *unc) errorTerm() float64 {
    return math.Sqrt(z.s)
}









func (z *unc) addC(a *unc, c float64) *unc {
    *z = *a
    z.n += c
    return z
}

func (z *unc) subC(a *unc, c float64) *unc {
    *z = *a
    z.n -= c
    return z
}

func (z *unc) addU(a, b *unc) *unc {
    z.n = a.n + b.n
    z.s = a.s + b.s
    return z
}
func (z *unc) subU(a, b *unc) *unc {
    z.n = a.n - b.n
    z.s = a.s + b.s
    return z
}


func (z *unc) mulC(a *unc, c float64) *unc {
    z.n = a.n * c
    z.s = a.s * c * c
    return z
}

func (z *unc) divC(a *unc, c float64) *unc {
    z.n = a.n / c
    z.s = a.s / (c * c)
    return z
}

func (z *unc) mulU(a, b *unc) *unc {
    prod := a.n * b.n
    z.n, z.s = prod, prod*prod*(a.s/(a.n*a.n)+b.s/(b.n*b.n))
    return z
}

func (z *unc) divU(a, b *unc) *unc {
    quot := a.n / b.n
    z.n, z.s = quot, quot*quot*(a.s/(a.n*a.n)+b.s/(b.n*b.n))
    return z
}


func (z *unc) expC(a *unc, c float64) *unc {
    f := math.Pow(a.n, c)
    g := f * c / a.n
    z.n = f
    z.s = a.s * g * g
    return z
}

func main() {
    x1 := newUnc(100, 1.1)
    x2 := newUnc(200, 2.2)
    y1 := newUnc(50, 1.2)
    y2 := newUnc(100, 2.3)
    var d, d2 unc
    d.expC(d.addU(d.expC(d.subU(x1, x2), 2), d2.expC(d2.subU(y1, y2), 2)), .5)
    fmt.Println("d:    ", d.n)
    fmt.Println("error:", d.errorTerm())
}