将10的幂写为紧凑的常数

Fil*_*ves 7 const go iota

我正在阅读最近发布的The Go编程语言,到目前为止它一直是一种喜悦(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
)
Run Code Online (Sandbox Code Playgroud)

作者进一步提到了10的权力:

该iota机制有其局限性.例如,由于没有取幂运算符,因此无法生成更熟悉的1000(KB,MB等)的幂.

我正在努力进行这项练习,因为看起来预期的解决方案比仅仅手动拼写1000的功能更为精细(特别是因为它出现之后iota).我觉得有一些聪明的方法可以用iota微妙的方式结合其他东西.

我想找到一种系统的方法来从1024的每个幂中减去"超额"量来获得1000的幂,但它让我无处可去.然后我查看二进制表示来尝试推断iota可能有用的一般模式,但同样,我什么也没得到.

我真的看不出如何在iota没有指数运算符的情况下从单个递增值()中产生1000 的幂.

有任何想法吗?

icz*_*cza 7

你自己引用了它:

该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 )
Run Code Online (Sandbox Code Playgroud)

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

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

如果我们想要无类型的整数常量,我们必须1000为KB.为了获得下一个,我们将自动转向将前一个标识符乘以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)
Run Code Online (Sandbox Code Playgroud)

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

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

你甚至可以从最后一个解决方案获得3个字符,如果你还引入了一个1-char长度const x,你多次使用它来进行乘法而不是*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)
Run Code Online (Sandbox Code Playgroud)

用rune文字

如果我们将1000常量指定为一个符文常量,我们甚至可以将它缩短一个字符,其符号是一个符号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)
Run Code Online (Sandbox Code Playgroud)

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

  • @FilipeGonçalves 基础类型必须是浮点数,ZB 和 YB 将溢出 uint64。有趣的是 const 声明会很好,但是一旦您尝试使用它们,您的代码就会失败。Golang 关于常量类型很有趣:https://blog.golang.org/constants (2认同)

Sal*_*ali 3

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

这是可能的,2^(10i)因为 go 引入了另一个初等函数整数求幂。因此,如果1 << y允许 y 为浮点数,您将能够修改代码以使用1 << (log2(10) * 3 * i). 这会起作用,因为这相当于解决10^(3i) = 2^y. 两边取log2y = log2(10) * 3 * i。

但遗憾的是,按位移位是整数运算。