Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Go中,带文字的浮点乘法和变量的浮点乘法为什么有区别?_Go_Floating Point - Fatal编程技术网

在Go中,带文字的浮点乘法和变量的浮点乘法为什么有区别?

在Go中,带文字的浮点乘法和变量的浮点乘法为什么有区别?,go,floating-point,Go,Floating Point,为什么Go中的以下各项不相等?这是一个bug,还是出于设计?如果是设计的,为什么会发生这种情况?这种行为是否在任何地方都有记录 产生: x == 10.1: true x*3.0 == 10.1*3.0: false x*3.0: 30.299999999999997 10.1*3.0: 30.3 请注意,正在执行相同的浮点运算,只是语法不同。那么,为什么结果不同呢?我希望10.1*3.0等于30.29999…如x*3.0示例所示。

为什么Go中的以下各项不相等?这是一个bug,还是出于设计?如果是设计的,为什么会发生这种情况?这种行为是否在任何地方都有记录

产生:

x == 10.1:         true
x*3.0 == 10.1*3.0: false
x*3.0:             30.299999999999997
10.1*3.0:          30.3

请注意,正在执行相同的浮点运算,只是语法不同。那么,为什么结果不同呢?我希望
10.1*3.0
等于
30.29999…
x*3.0
示例所示。

Go中的常量和数字文字是非类型化的,具有无限精度。当必须将其存储为特定类型时,该类型的边界将适用。因此,当您声明
x:=10.1
时,该文本将转换为
浮点值
,并失去一些精度。但是,当您专门执行
10.1*3.0
时,这些都有其全部精度

请参阅本文中的“Floats”标题

数值常量存在于任意精度的数值空间中;他们 这些都是正数。但是当它们被分配到一个变量时 值必须能够适应目标。我们可以申报 具有非常大值的常数:

const Huge = 1e1000 
-毕竟,这只是一个数字,但我们无法分配它,甚至无法打印它。此语句甚至不会编译:

fmt.Println(Huge)
错误是“常量1.00000e+1000溢出浮点64”,这是 对。但是巨大的可能是有用的:我们可以在表达式中使用它 其他常量,如果结果不正确,则使用这些表达式的值 可以在浮点64的范围内表示

它实际上是如何做到这一点的,特别是在给定的
巨大的
情况下,我不知道

数值常量表示任意精度和do的精确值 不要溢出。因此,没有常数表示 IEEE-754负零、无穷大和非数字值

实现限制:尽管数值常量具有任意 在语言中,编译器可以使用 精度有限的内部表示。也就是说,每个 实施必须:

  • 表示至少256位的整数常量

  • 表示浮点常量,包括 复数常量,尾数至少为256位,带符号 至少16位的二进制指数

  • 如果无法表示整型常量,请给出错误 没错

  • 如果无法表示浮点或复数,请给出错误 由于溢出而导致的常量

  • 如果无法表示,则四舍五入到最近的可表示常数 由于精度限制而产生的浮点或复数常量

数字类型表示整数值或浮点值集。 预先声明的独立于体系结构的浮点数字类型 它们是:



常量在编译时使用包进行任意精度的运算。变量用于浮点运算,通常由硬件提供。

可能与Ken重复,谢谢。我不认为这是同一个问题,因为这个问题是关于许多语言中众所周知的浮点数学精度问题。在这里,执行相同的浮点运算,但只使用不同的语法。但结果却不同。为了澄清,我希望
10.1*3.0
等于
30.299999…
,如
x*3.0
示例中所示。“正在执行相同的浮点数学”这句话是错误的。有趣。这让我想到,当一个特定的常量或文字不能在
float64
(如10.1或.1)中精确表达时,Go会抛出一个警告,就像一个巨大的数字溢出int或float类型一样。即10.1不能真正“适合”于
浮点64
,或任何长度的浮点。可能是设计决定不这样做,因为警告非常常见。编译器将它们存储为
big.Float
s(或
big.Int
s或
big.Rat
s),这并不奇怪。记住,Go编译器是用Go编写的:)顺便说一句:最接近10.1的是10.100000381…这是最终的答案!我刚想在编辑我刚刚放弃的答案时推测一下这种编译时算法:)谢谢。这还特别说明,如果由于精度限制,编译器无法表示浮点常量,则编译器不应抛出警告或错误(但在溢出的情况下将抛出错误)。
fmt.Println(Huge)
float32     the set of all IEEE-754 32-bit floating-point numbers
float64     the set of all IEEE-754 64-bit floating-point numbers