如何从两个半部分中检索更大的整数?

huangapple go评论85阅读模式
英文:

How to retrieve bigger int from two halves?

问题

以下是代码的翻译:

package main

import (
	"fmt"
	"math"
)

type BiggerInt struct {
	Upper int64
	Lower int64
}

const (
	bigger    = 9223372036854775808543522345
	divisor64 = 1 << 64
)

func main() {
	var x BiggerInt
	x.Upper = bigger / divisor64
	x.Lower = bigger % divisor64
	fmt.Println(x.Lower + (x.Upper * int64(math.Pow(2, 64)))) // 期望输出:9223372036854775808543522345,实际输出:543522345
}

如何从 x.Lowerx.Upper 中获取更大的整数?

英文:

Below is the code:

package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
)

type BiggerInt struct {
	Upper int64
	Lower int64
}

const (
	bigger    = 9223372036854775808543522345
	divisor64 = 1 &lt;&lt; 64
)

func main() {
	var x BiggerInt
	x.Upper = bigger / divisor64
	x.Lower = bigger % divisor64
	fmt.Println(x.Lower + (x.Upper * int64(math.Pow(2, 64)))) // expecting 9223372036854775808543522345, got: 543522345
}

How to retrieve bigger int from x.Lower & x.Upper?

答案1

得分: 4

重要提示:我将为您提供翻译服务,但请注意,我只会返回翻译好的部分,不会回答关于翻译的问题。

以下是您提供的内容的翻译:

重要的是要注意,const 常量是无类型的,其类型是根据上下文确定的。

const (
    bigger    = 9223372036854775808543522345
    divisor64 = 1 << 64
)

这两个数字都无法适应 go 中最大的 int64 整数类型,但以下数学运算:

var x BiggerInt
x.Upper = bigger / divisor64  // 在编译时解析...
x.Lower = bigger % divisor64  // ...因此适应于 `int64`

通过在编译时解析赋值,可以避免任何溢出问题,因为这些赋值的值适应于 int64 类型。

使用任何基本的 go 类型(没有 int128)无法将其重新转换为原始的无类型 bigger。因此,可以使用标准库的 math/big 包:

import "math/big"

t := big.NewInt(upper)
t.Lsh(t, 64)
t.Add(t, big.NewInt(lower))

fmt.Println(t) // 9223372036854775808543522345

链接:https://go.dev/play/p/bHTOssconQa

英文:

It's important to note that const numbers are untyped - and will have type applied based on context.

const (
    bigger    = 9223372036854775808543522345
    divisor64 = 1 &lt;&lt; 64
)

Neither of these numbers fit into go's largest int64 integer type, however the following math:

var x BiggerInt
x.Upper = bigger / divisor64  // resolved at compile-time ...
x.Lower = bigger % divisor64  // ... so will fit into `int64`

skirts any overflow issues, since the assignment values are resolved at compile time and do fit in int64 types.

Trying to reconstitute this into the original (untyped bigger) is not possible with any of the base go types (there is no int128). So, instead, use the standard library's math/big package:

import &quot;math/big&quot;

t := big.NewInt(upper)
t.Lsh(t, 64)
t.Add(t, big.NewInt(lower))

fmt.Println(t) // 9223372036854775808543522345

https://go.dev/play/p/bHTOssconQa

答案2

得分: 1

不清楚你的期望是什么。但是如果你不知道的话,math/big 包实现了任意精度的算术运算(大数)。

package main

import (
	"fmt"
	"math/big"
)

type BiggerInt struct {
	Upper int64
	Lower int64
}

const (
	bigger    = 9223372036854775808543522345
	divisor64 = 1 << 64
)

func main() {
	var x BiggerInt
	x.Upper = bigger / divisor64
	x.Lower = bigger % divisor64

	result := &big.Int{}
	result.Lsh(big.NewInt(x.Upper), 64)
	result.Add(result, big.NewInt(x.Lower))
	fmt.Println(result)
	// output:
	//	9223372036854775808543522345
}
英文:

It's not clear what you are expecting. But in case that you don't know, the math/big package implements arbitrary-precision arithmetic (big numbers).

package main

import (
	&quot;fmt&quot;
	&quot;math/big&quot;
)

type BiggerInt struct {
	Upper int64
	Lower int64
}

const (
	bigger    = 9223372036854775808543522345
	divisor64 = 1 &lt;&lt; 64
)

func main() {
	var x BiggerInt
	x.Upper = bigger / divisor64
	x.Lower = bigger % divisor64

	result := &amp;big.Int{}
	result.Lsh(big.NewInt(x.Upper), 64)
	result.Add(result, big.NewInt(x.Lower))
	fmt.Println(result)
	// output:
	//	9223372036854775808543522345
}

huangapple
  • 本文由 发表于 2023年4月16日 21:46:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76028130.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定