uint(-5.0),其中参数是 float64,= 18446744073709551611?

uint(-5.0), where parameter is a float64, = 18446744073709551611?

提问人:Marc Le Bihan 提问时间:5/26/2023 最后编辑:Marc Le Bihan 更新时间:5/26/2023 访问量:101

问:

在 Go 教程的第 13 步中,我稍微更改了脚本

package main

import (
    "fmt"
    "math"
)

func main() {
    var x, y int = 3, 4
    var f float64 = math.Sqrt(float64(x*x + y*y))
    var z uint  = uint(f)
    fmt.Println(x, y, z, f)
}

这返回:3 4 5 5,很好。

但是当我做这个改变时:否定:f

func main() {
    var x, y int = 3, 4
    var f float64 = - math.Sqrt(float64(x*x + y*y))
    var z uint  = uint(f)
    fmt.Println(x, y, z, f)
}

它响应:3 4 18446744073709551611 -5

为什么该方法将 -5.0 转换为 18446744073709551611uint

难道没有东西 - 算法吗?- 试图检查它在下面做什么?
这就像该方法在二进制级别上残酷地从带有尾数和指数的浮点数转换为整数?
uint

发生了什么事情?

enter image description here

如果我被误导了,并且这些方法不是我认为的转换函数,
而是像您在 C 中找到的转换方法,那么确保以下条件的转换函数
是什么:
uint(uint)f

uint z = anotherFunction(any float64)

将返回该浮点数的正整数值吗?

go 浮点 类型转换 uint

评论

3赞 mkopriva 5/26/2023
uint不是一种方法,而是一种类型。 是转换表达式,因此是将 的值转换为 类型的值的转换。的取值范围是通过,注意不能保存负值,还要注意非常量值的转换总是产生一个有效值;没有溢出的迹象。T(x)uint(f)fuintuint018446744073709551615uint
3赞 mkopriva 5/26/2023
正式地说,这是一个转换,Go 没有类型转换。但是,您可以随意称呼它,只是不要指望其他人会服从您的自定义术语。
3赞 Volker 5/26/2023
不,这是一种转换。Go 中没有类型转换。这就是表示无符号整数和有符号整数的工作方式。
2赞 mkopriva 5/26/2023
uint(math.Abs(f))@MarcLeBihan
3赞 JimB 5/26/2023
如果这真的是一个“强制转换”,结果将是 ,即解释为 .转换将数字转换为整数,然后将其转换为无符号整数。这似乎是武断的,因为确实如此,因为语言需要做出任意决定如何处理转换,而这是不可能的。是的,某些转换可能等同于类型转换,但不是全部。13840687554816376832float64uint64

答:

5赞 icza 5/26/2023 #1

的值为负数:。当您将其转换为无符号类型的值时,您会期望什么?无符号类型具有有效的范围/表示形式,其中没有空间。f-5.0-5

Go(像大多数其他语言一样)使用 2 的补码来表示整数。将有符号整数转换为无符号整数时,将保留表示形式(内存中的二进制数据),但数字的解释方式会有所不同。

通常,将负符号值转换为无符号值时,可以使用以下方法计算结果:

result: MAX_VALUE + x + 1 = MAX_VALUE - ABS(x) + 1

因此,例如,当将类型转换为 时,结果将是:-5int8uint8

255 - 5 + 1 = 251

将类型转换为:-5int64uint64

18446744073709551615 - 5 + 1 = 18446744073709551611

(注意:和的大小取决于平台,在 Go Playground 上,它的大小为 64 位,与 和 相同。intuintint64uint64

最后一个缺失的部分:your 是 类型 。从规范转换为整数: 转换: 数值类型之间的转换:ffloat64float64

对于非常量数值的转换,适用以下规则:

[...]

  1. 浮点数转换为整数时,分数将被丢弃(截断为零)。

所以被转换为 ,那么可以使用上面的算法来解释为类型的值时会是什么样子。-5.0-5uint

评论

0赞 Marc Le Bihan 5/26/2023
所以这不是转换,而是铸造。转换具有目标:返回相同的数字。如果你告诉一个数学家-5.0,因为正整数对值18446744073709551611,他不会相信你。你会建议他用什么方法将任何浮点数转换为uint?
1赞 mkopriva 5/26/2023
“转换的目标:返回相同的数字。”--错。请参阅官方语言规范:“转换将表达式的类型更改为转换指定的类型。 @MarcLeBihan
1赞 mkopriva 5/26/2023
使用数学。Abs 获取绝对值 ()。|-5.0|
1赞 Eric Postpischil 5/26/2023
@MarcLeBihan:转化的目标是在新类型中返回相同的值,但当无法实现该目标时(因为在新类型中无法表示相同的值),则必须发生其他操作。强制转换执行转换。
1赞 Eric Postpischil 5/26/2023
@mkopriva:您引用的文本并不表明转化的目标是在新类型中产生相同的值是错误的。它只是说转化改变了类型,而不是它对价值做了什么或目标价值是什么。