Тип печати константы numberri c вызывает переполнение - PullRequest
0 голосов
/ 03 мая 2020

Я новичок в Go и в настоящее время слежу за A Tour of Go.

Я сейчас на странице Нумерация c Константы . Ниже приведена сокращенная версия кода, который выполняется на этой странице:

package main
import "fmt"
const Big = 1 << 100
func needFloat(x float64) float64 {
    return x * 0.1
}
func main() {
    fmt.Println(needFloat(Big))
    // fmt.Printf("Type of Big %T", Big)
}

этот код успешно компилируется с выводом 1.2676506002282295e+29

Следующий код, однако, не будет компилироваться и давать ошибка:

package main
import "fmt"
const Big = 1 << 100
func needFloat(x float64) float64 {
    return x * 0.1
}
func main() {
    fmt.Println(needFloat(Big))
    fmt.Printf("Type of Big %T", Big)
}

Вывод: ./prog.go:9:13: constant 1267650600228229401496703205376 overflows int

Почему вы думаете, что это произошло? Я надеюсь, что вы любезно объясните.

Ответы [ 3 ]

1 голос
/ 03 мая 2020

Константа Big является нетипизированной константой. Нетипизированная константа может быть произвольно большой, и она не должна вписываться в пределы любого предопределенного типа. Он интерпретируется и усекается в используемом контексте.

Функция needFloat получает аргумент float64. В этом случае Big преобразуется в float64 и используется таким образом.

Когда вы используете его для Printf, он пытается передать его как int, поскольку он не является десятичным число (в противном случае это преобразовало бы его в float64), и это вызывает переполнение Передайте его как float64 (большой), и он должен работать.

0 голосов
/ 03 мая 2020

Нетипизированная константа n должна быть преобразована в тип, прежде чем ее можно будет присвоить параметру interface {} в вызове fmt.Println.

fmt.Println(a ...interface{})

Когда тип не может быть выведен из контекст, нетипизированная константа преобразуется в bool, int, float64, complex128, строку или руну в зависимости от формата константы.

В этом случае константа является целым числом, но n больше, чем максимальное значение типа int.

Однако n может быть представлено как float64.

const n = 9876543210 * 9876543210
fmt.Println(float64(n))

Для точного представления больших чисел, пакет math / big реализует арифметика произвольной точности c. Он поддерживает целые числа со знаком, рациональные числа и числа с плавающей точкой.

Это взято из https://yourbasic.org/golang/gotcha-constant-overflows-int/.

0 голосов
/ 03 мая 2020

Полагаю, причина в том, что Big вычисляется (то есть приводится непосредственно перед передачей в needFloat, а вместо этого вычисляется как int64 перед Printf. В качестве доказательства следующее утверждение вычисляется правильно:

package main
import "fmt"
const Big = 1 << 100

func main() {
    fmt.Printf("Type of Big %T", float64(Big))
}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...