properly handle integer conversions for int/uint fields in structs
diff --git a/mapstructure.go b/mapstructure.go
index b7b3edc..9da5586 100644
--- a/mapstructure.go
+++ b/mapstructure.go
@@ -65,12 +65,12 @@
 	switch k {
 	case reflect.Bool:
 		fallthrough
+	case reflect.String:
+		return decodeBasic(name, data, val)
 	case reflect.Int:
 		fallthrough
-	case reflect.String:
-		fallthrough
 	case reflect.Uint:
-		return decodeBasic(name, data, val)
+		return decodeInt(name, data, val)
 	case reflect.Struct:
 		return decodeStruct(name, data, val)
 	case reflect.Map:
@@ -103,6 +103,59 @@
 	return nil
 }
 
+func decodeInt(name string, data interface{}, val reflect.Value) error {
+	dataVal := reflect.ValueOf(data)
+	if !dataVal.IsValid() {
+		// This should never happen
+		panic("data is invalid")
+	}
+
+	dataKind := dataVal.Kind()
+	if dataKind >= reflect.Int && dataKind <= reflect.Int64 {
+		dataKind = reflect.Int
+	} else if dataKind >= reflect.Uint && dataKind <= reflect.Uint64 {
+		dataKind = reflect.Uint
+	} else if dataKind >= reflect.Float32 && dataKind <= reflect.Float64 {
+		dataKind = reflect.Float32
+	} else {
+		return fmt.Errorf(
+			"'%s' expected type '%s', got unconvertible type '%s'",
+			name, val.Type(), dataVal.Type())
+	}
+
+	valKind := val.Kind()
+	if valKind >= reflect.Int && valKind <= reflect.Int64 {
+		valKind = reflect.Int
+	} else if valKind >= reflect.Uint && valKind <= reflect.Uint64 {
+		valKind = reflect.Uint
+	}
+
+	switch dataKind {
+	case reflect.Int:
+		if valKind == reflect.Int {
+			val.SetInt(dataVal.Int())
+		} else {
+			val.SetUint(uint64(dataVal.Uint()))
+		}
+	case reflect.Uint:
+		if valKind == reflect.Int {
+			val.SetInt(int64(dataVal.Uint()))
+		} else {
+			val.SetUint(dataVal.Uint())
+		}
+	case reflect.Float32:
+		if valKind == reflect.Int {
+			val.SetInt(int64(dataVal.Float()))
+		} else {
+			val.SetUint(uint64(dataVal.Float()))
+		}
+	default:
+		panic("should never reach")
+	}
+
+	return nil
+}
+
 func decodeMap(name string, data interface{}, val reflect.Value) error {
 	dataVal := reflect.Indirect(reflect.ValueOf(data))
 	if dataVal.Kind() != reflect.Map {
diff --git a/mapstructure_examples_test.go b/mapstructure_examples_test.go
index e7449c5..0e1af6b 100644
--- a/mapstructure_examples_test.go
+++ b/mapstructure_examples_test.go
@@ -4,14 +4,14 @@
 	"fmt"
 )
 
-type Person struct {
-	Name   string
-	Age    int
-	Emails []string
-	Extra  map[string]string
-}
-
 func ExampleDecode() {
+	type Person struct {
+		Name   string
+		Age    int
+		Emails []string
+		Extra  map[string]string
+	}
+
 	// This input can come from anywhere, but typically comes from
 	// something like decoding JSON where we're not quite sure of the
 	// struct initially.
@@ -36,6 +36,13 @@
 }
 
 func ExampleDecode_errors() {
+	type Person struct {
+		Name   string
+		Age    int
+		Emails []string
+		Extra  map[string]string
+	}
+
 	// This input can come from anywhere, but typically comes from
 	// something like decoding JSON where we're not quite sure of the
 	// struct initially.
@@ -56,7 +63,7 @@
 	// 5 error(s) decoding:
 	//
 	// * 'Name' expected type 'string', got 'int'
-	// * 'Age' expected type 'int', got 'string'
+	// * 'Age' expected type 'int', got unconvertible type 'string'
 	// * 'Emails[0]' expected type 'string', got 'int'
 	// * 'Emails[1]' expected type 'string', got 'int'
 	// * 'Emails[2]' expected type 'string', got 'int'
diff --git a/mapstructure_test.go b/mapstructure_test.go
index 663f520..cda1449 100644
--- a/mapstructure_test.go
+++ b/mapstructure_test.go
@@ -75,6 +75,20 @@
 	}
 }
 
+func TestBasic_IntWithFloat(t *testing.T) {
+	t.Parallel()
+
+	input := map[string]interface{}{
+		"vint": float64(42),
+	}
+
+	var result Basic
+	err := Decode(input, &result)
+	if err != nil {
+		t.Fatalf("got an err: %s", err)
+	}
+}
+
 func TestMap(t *testing.T) {
 	t.Parallel()