0

I have this piece of code that is suppose to print the area of individual shapes and then print the total area (sum of the individual areas), but there seem to be a problem somewhere in the addition when I use interfaces and variadic functions. The program is written in GoLang and below is the code;

/* Program that interacts with shapes */

/* Calculating the area of basic shapes e.g Circle, Rectangle */

package main

import ("fmt"; "math")

/* Adding the interface support */
type Shape interface {
    area() float64
}

/* Struct for Circle */
type Circle struct {
    x, y, r float64
}

/* Struct for Rectangle */
type Rectangle struct {
    x1, y1, x2, y2 float64
}

/* Calculation of distance */
func distance(x1, y1, x2, y2 float64) float64 {
    a := x2 - x1
    b := y2 - y1
    return math.Sqrt(a*a + b*b)
}

/* Area of the rectangle */
func (r *Rectangle) area() float64 {
    l := distance(r.x1, r.y1, r.x1, r.y2)
    w := distance(r.x1, r.y1, r.x2, r.y1)

    return l * w
}

/* Area of the circle */
func (c *Circle) area() float64 {
    return math.Pi * c.r * c.r
}

/* Interface is really useful when finding the total area i.e. the sum of 
   all the areas of each of the shapes
*/
func totalArea(shapes ...Shape) float64 {
    var area float64
    for _, s := range shapes {
        area += s.area()
    }
    return area
}

/* This is the main function */
func main() {
    c := Circle{0, 0, 5}

    r := Rectangle{0, 0, 10, 10}

    fmt.Println("Area of the rectangle is: ", r.area())

    fmt.Println("Area of the circle is: ", c.area())

    fmt.Println("Sum of the areas: ", totalArea(&c, &r))
}

I ran this code on my Mac OS X El Capitan, core i5, 8GB RAM and below is my output

Area of the rectangle is:  100
Area of the circle is:  78.53981633974483
Sum of the areas:  178.53981633974485

From the results as you can see, there is a small issue, the expected sum of the areas should be: 178.53981633974483 but I get 178.53981633974485 which is 0.00000000000002 different or deviation from the expected results, please can anyone help me out with why it is like this?

I am not quite sure if its a problem with the math library in GoLang since it just has to do a normal addition of the two areas? Or is it that GoLang recalculates the area before passing it to totalArea() then does some approximation I don't quite get it? Or is it my computer (one can never tell)?

Thanks for your help in advance.

Derick Alangi
  • 1,080
  • 1
  • 11
  • 31
  • @tkausl, I think that solves the problem. Wow, its really weird. Hardware related, that makes sense. Architectures are different and hence the way data is stored.. Thanks. – Derick Alangi Oct 06 '16 at 01:55

1 Answers1

0

This is the behaviour of floating point arithmetic and its precision rather than anything specific to golang.

Theres a few good resources regarding float precision.

here is a snippet that illustrates your issue more simply:

https://play.golang.org/p/Jhlnt0L13T

If you do need arbitrary precision then you may want to look at:

https://golang.org/pkg/math/big/

danmux
  • 2,735
  • 1
  • 25
  • 28