7

我正在阅读最近发布的 The Go Programming Language,到目前为止一直很开心(Brian Kernighan 是作者之一,无论如何,除了卓越之外,我别无所求)。

我在第 3 章遇到了以下练习:

练习 3.13const尽可能紧凑地 编写KB、MB 到 YB 的声明。

注意:在此上下文中,KB、MB 等表示 1000 的幂)

前面有一节iota介绍了一个有用的常量生成器机制;特别是,上一段展示了一种将 1024 的幂定义为常量的简洁的方式:

const (
    _ = 1 << (10 * iota)
    KiB
    MiB
    GiB
    TiB
    PiB
    EiB
    ZiB
    YiB
)

作者进一步提到了 10 的幂:

iota机制有其局限性。例如,不可能生成更熟悉的 1000(KB、MB 等)的幂,因为没有求幂运算符。

我在这个练习中苦苦挣扎,因为看起来预期的解决方案比简单地手工拼出 1000 的幂要复杂一些(特别是因为它出现在iota引入之后)。我觉得有一些聪明的方法可以做到这一点,它iota以一种微妙的方式与其他东西结合使用。

我想过找到一种系统的方法,从 1024 的每个幂中减去“多余”的数量,以获得 1000 的幂,但它让我无处可去。然后我查看了二进制表示,试图推断出iota可能有用的一般模式,但同样,我什么也没得到。

如果没有幂运算符,我真的看不出如何从单个递增值 ( iota) 中生成 1000 的幂。

有任何想法吗?

4

2 回答 2

9

您自己引用了它:

iota机制有其局限性。例如,不可能生成更熟悉的 1000(KB、MB 等)的幂,因为没有求幂运算符。

尽管他们一无所知,但作者不希望您仍然找到方法。作者希望您尽可能紧凑地为 KB、MB 等创建常量声明。

使用浮点文字

这是一个紧凑的方式。这利用了带有指数部分的浮点文字。想一想:写作1e3比写作还要短1000(更不用说其余的......)。

它还将所有标识符压缩为一个常量规范,因此我们将=符号减为 1。

在这里,只有一行(67 个字符,不含空格):

const ( KB, MB, GB, TB, PB, EB, ZB, YB = 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24 )

请注意,由于我们使用了浮点文字,因此常量标识符 ( KB, MB...) 表示浮点常量,即使文字的小数部分为零。

使用整数文字,KB用作乘数

如果我们想要无类型的整数常量,我们必须1000KB. 为了得到下一个,我们会自动将前一个标识符乘以1000. 但请注意,我们也可以将下一个乘以,KB因为它恰好是1000- 但要短两个字符:)。

所以这里是无类型整数常量声明(77 个字符,没有空格):

const (KB,MB,GB,TB,PB,EB,ZB,YB = 1000,KB*KB,MB*KB,GB*KB,TB*GB,PB*KB,EB*KB,ZB*KB)

(很抱歉删除了空格,但希望它适合一行。)

使用整数文字,使用额外的xconst 作为乘数

如果您还引入了一个 1-char 长度的 const x,您甚至可以从最后一个解决方案中获得 3 个字符,您多次使用它来进行乘法而不是*KB

使用额外的xconst (74 个字符,无空格):

const (x,KB,MB,GB,TB,PB,EB,ZB,YB = 1000,x,x*x,MB*x,GB*x,TB*GB,PB*x,EB*x,ZB*x)

rune字面

如果我们将1000常量指定为 rune 常量,我们甚至可以将其再缩短一个字符,其中 rune 的代码点为1000,即'Ϩ'- 少 1 个字符 :)

使用rune文字'Ϩ'const (73 个字符,无空格):

const (x,KB,MB,GB,TB,PB,EB,ZB,YB = 'Ϩ',x,x*x,MB*x,GB*x,TB*GB,PB*x,EB*x,ZB*x)

请注意,这些将是符文常量,但就像所有其他数字常量一样,它们表示任意精度的值并且不会溢出。

于 2015-12-08T00:00:43.910 回答
3

我会说这是不可能的,因为您想要将一个函数表示为某个函数,10^(3i)其中i是一个正整数,其中是您的基本 go 函数(+、-、/、*)的合成函数。f(i)f

之所以可能,2^(10i)只是因为 Go 引入了另一个基本函数整数幂运算。因此,如果1 << y允许 y 浮动,您将能够修改代码以使用1 << (log2(10) * 3 * i). 这会起作用,因为这相当于解决10^(3i) = 2^y. 取双方的log2 y = log2(10) * 3 * i

但可悲的是,按位移位是一个整数运算。

于 2015-12-07T00:39:40.970 回答