相关疑难解决方法(0)

去打印大量

我目前正在做 Go Lang 教程,准确地说是“数值常量”。示例代码以以下语句开头:

const (
    // Create a huge number by shifting a 1 bit left 100 places.
    // In other words, the binary number that is 1 followed by 100 zeroes.
    Big = 1 << 100
    // Shift it right again 99 places, so we end up with 1<<1, or 2.
    Small = Big >> 99
)
Run Code Online (Sandbox Code Playgroud)

常量Big显然很大,我正在尝试打印它及其类型,如下所示:

fmt.Printf("%T", Big)
fmt.Println(Big)
Run Code Online (Sandbox Code Playgroud)

但是,我对这两行都收到以下错误:

# 命令行参数 ./compile26.go:19: 常量 1267650600228229401496703205376 溢出 int

我会尝试将 Big 转换为其他类型,例如uint64,它溢出了相同的错误,或者只是将其转换为字符串,但是在尝试时Big.String()出现以下错误: …

integer-overflow biginteger go

6
推荐指数
1
解决办法
1843
查看次数

为什么0.1 + 0.2在Google Go中获得0.3?

只要使用浮点数,0.1就不能在内存中精确表示,所以我们知道这个值通常是0.10000000000000004.

但是当使用go时加0.1和0.2.我得到0.3.

fmt.Println(0.1 + 0.2)
// Output : 0.3
Run Code Online (Sandbox Code Playgroud)

为什么0.3出来而不是0.30000000000000004?

precision go

6
推荐指数
1
解决办法
427
查看次数

为什么golang中的64位溢出没有留下位移?

我正在看看A Tour of Go,我对它们的基本类型感到困惑.示例:

MaxInt uint64     = 1<<64 - 1
Run Code Online (Sandbox Code Playgroud)

不应该在无符号的64位整数中向左移动1 64个位置导致溢出(也就是稍微移过MSB一点)?

但是,在将行更改为以下内容之前,编译器不会抱怨:

MaxInt uint64     = 1<<65 - 1

./basic-types.go:5: constant 36893488147419103231 overflows uint64
Run Code Online (Sandbox Code Playgroud)

如果我编写一些代码来迭代不同长度的左移,包括按照上面的例子中的65移动导致编译器barf,我看到两件事:

  1. 它的行为与我预期的一样,因为1<<63在MSB中1可能是uint64

  2. 它不再溢出(嗯?!?!)

码:

package main

import "fmt"

func main() {
    for i := 60; i < 66; i++ {
        var j uint64 = 1 << uint64(i) - 1
        fmt.Printf("%2d | %64b | %#18x\n", i, j, j)

    }
Run Code Online (Sandbox Code Playgroud)

输出:

60 |     111111111111111111111111111111111111111111111111111111111111 |  0xfffffffffffffff
61 |    1111111111111111111111111111111111111111111111111111111111111 | 0x1fffffffffffffff
62 |   11111111111111111111111111111111111111111111111111111111111111 …
Run Code Online (Sandbox Code Playgroud)

bit-manipulation go bitwise-operators

5
推荐指数
1
解决办法
1066
查看次数

对于常量表达式和其他表达式,编译器的评估是否有所不同

为什么下面的代码无法编译?

package main

import (
    "fmt"
    "unsafe"
)

var x int = 1

const (
    ONE     int = 1
    MIN_INT int = ONE << (unsafe.Sizeof(x)*8 - 1)
)

func main() {
    fmt.Println(MIN_INT)

}
Run Code Online (Sandbox Code Playgroud)

我收到一个错误

main.go:12:常量2147483648溢出int

以上陈述是正确的.是的,2147483648溢出int(在32位架构中).但是班次操作应该导致负值,即-2147483648.

但相同的代码工作,如果我将常量更改为变量,我得到预期的输出.

package main

import (
    "fmt"
    "unsafe"
)

var x int = 1

var (
    ONE     int = 1
    MIN_INT int = ONE << (unsafe.Sizeof(x)*8 - 1)
)

func main() {
    fmt.Println(MIN_INT)

}
Run Code Online (Sandbox Code Playgroud)

evaluation bit-manipulation bit-shift go bitwise-operators

4
推荐指数
1
解决办法
450
查看次数

为什么%T不打印我常量的类型?

我正在学习使用官方旅游/教程的golang.在其中一个例子中,我看到一个说明An untyped constant takes the type needed by its context.

我正在尝试这个:

package main

import "fmt"

const (
    // Create a huge number by shifting a 1 bit left 100 places.
    // In other words, the binary number that is 1 followed by 100 zeroes.
    Big = 1 << 100
)

func main() {
    fmt.Printf("Big is of type %T\n", Big)
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时失败了:

# command-line-arguments
./compile63.go:12:13: constant 1267650600228229401496703205376 overflows int
Run Code Online (Sandbox Code Playgroud)

为什么我无法通过这种方式发现常数的类型?(请注意我是一个完全的菜鸟,很可能还没有发现足够的语言能够自己解决这个问题).

types constants go

3
推荐指数
1
解决办法
435
查看次数

Gloang移位运算符转换

我不能在golang如何理解1<<s返回0如果var s uint = 33。但是1<<33返回8589934592。移位运算符转换如何以0值结束。

我正在阅读语言规范,并停留在本节中:https : //golang.org/ref/spec#Operators

特别是来自文档的这一段:

“移位表达式中的右操作数必须具有无符号整数类型,或者是可由uint类型的值表示的无类型常量。 如果非恒定移位表达式的左操作数是无类型常量,则首先将其隐式转换为该类型它会假设是否仅将shift表达式替换为其左操作数。”

来自Golang官方文档的一些示例:

var s uint = 33
var i = 1<<s                  // 1 has type int
var j int32 = 1<<s            // 1 has type int32; j == 0
var k = uint64(1<<s)          // 1 has type uint64; k == 1<<33
Run Code Online (Sandbox Code Playgroud)

更新:

另一个非常相关的问题,例如:

package main

import (
    "fmt"
)

func main() {
v := int16(4336)
    fmt.Println(int8(v))
}
Run Code Online (Sandbox Code Playgroud)

该程序返回 …

type-conversion go operator-keyword

3
推荐指数
1
解决办法
90
查看次数

按时间段的分数睡觉

有人能告诉我为什么这样有效:

s := time.Hour/73.0
fmt.Println("sleeping: ", s)
time.Sleep(s)
Run Code Online (Sandbox Code Playgroud)

但这失败了:

d := 73.0
s := time.Hour/d
fmt.Println("sleeping: ", s)
time.Sleep(s)
Run Code Online (Sandbox Code Playgroud)

这是错误:

invalid operation: time.Hour / d (mismatched types time.Duration and float64)
Run Code Online (Sandbox Code Playgroud)

time types const type-conversion go

1
推荐指数
1
解决办法
484
查看次数

Go中任意精度常数的目的是什么?

Go具有任意大小和精度的无类型精确数字常量。该规范要求所有编译器支持至少256位的整数,并且至少浮动272位(尾数为256位,指数为16位)。因此,要求编译器忠实准确地表示如下表达式:

const (
    PI       = 3.1415926535897932384626433832795028841971
    Prime256 = 84028154888444252871881479176271707868370175636848156449781508641811196133203
)
Run Code Online (Sandbox Code Playgroud)

这很有趣......,但我无法找到任何方式实际使用任何这种持续超过64位的具体类型的最大精度int64uint64float64complex128(这只是一对float64值)。即使是标准库中的大数字类型 big.Intbig.Float也无法从大数字常量中进行初始化-必须从字符串常量或其他表达式中反序列化它们。

基本机制很明显:这些常量仅在编译时存在,并且必须强制为某个可在运行时表示的值才能在运行时使用。它们是仅在代码中和编译期间存在的语言构造。您无法在运行时检索常量的原始值;它不存储在已编译程序本身的某个地址中。

因此问题仍然存在:为什么在实践中无法使用巨大的常量时,语言为什么要这么点呢?

constants go

-1
推荐指数
1
解决办法
68
查看次数